M : Modelcss
V : Viewhtml
C : Controller前端
不知道大家玩过Struts没,如今Struts都是一些传统的老项目维护在使用,基本是被市场淘汰了;web
以前Struts出过几回比较重大失误,虽而后面也在更新,可是你们内心都怕了,所谓一朝被蛇咬,十年怕井绳,而SpringMVC又是由Spring提供的一个web层框架,Spring背后的社区力量可想而知,现在已经成为web层最优秀的框架;面试
SpringMVC主要是由前端控制器,处理器映射器,处理器适配器,后端控制器,视图解析器等组成spring
第一步:用户向服务器发送请求,请求被Spring前端控制器 DispatcherServlet捕获;数据库
第二步: DispatcherServlet调用HandlerMapping对请求URL进行解析,获得请求资源标识符(URL),得到该Handler配置的全部相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;后端
第三步: DispatcherServlet 根据得到的Handler,选择一个合适的HandlerAdapter。(附注:若是成功得到HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)跨域
第四步:提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程当中,根据你的配置,Spring将帮你作一些额外的工做: >> 1. HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息 >> 2. 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等 >> 3. 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期 >> 4. 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中数组
第五步: Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
第六步:根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
第七步:ViewResolver 结合Model和View,将模型数据填充至视图中
第八步:将渲染结果返回给客户端。
:http://www.javashuo.com/article/p-yjrakpyr-ka.html
ModelAndView: 通常不用 ,Model装载数据,View指定视图
Void : 通常用于返回Json数据,固然也能够在形参上定义request和response
String : 返回的是视图名,能够转发和重定向 return " redirect / forward:index" ; //配合视图解析器
当方法上有@ResponsaBody注解时,mvc不会解析其为跳转路径
POJO:配合@ResponsaBody使用
@Conrtoller @RequestBody @Requestarem @ResponseBody
@ResponsaBody注解:将返回的数据封装到Http Response Body中,不会放置到Model中,mvc也不会解析为跳转路径
Json是默认的的一种返回格式(须要相关 jar 的支持)
@RequestBody注解 :能够将请求的Json字符串中的值绑定到Bean上
@RequestMapping : 定义出路起映射规则 value={"/itemList","listItem"},能够是单个值也能够是多个映射规则 数组形式
简单类型参数绑定 保证请求参数key和形参名保持一致便可(8中基本数据类型和包装类和String均受理)
@RequestParam : 请求参数中key和形参名称不一致是使用,进行参数绑定
@RequestParam(value=" ",required=true,default=" ") // 参数名称 -- 是否必须有值 -- 默认给值
绑定POJO,要求参数中的key 和POJO中的属性名得保持一致
绑定包装POJO,页面请求参数以下 stu.name 对应的包装类Class类内有一属性 stu stu内有一属性name
使用简单类型数组接收批量传递的简单数据类型数据,好比String[ ] 或者 POJO内的属性 String[ ]
好比这个:http://localhost:8080/xxx/deleteItem?id=1&id=2&id=3 就能够用Integer[ ] 接收
若相拥List去接收传递的请求参数的话,List必须是一个POJO类内的一个属性,而不能直接以List接收
若是要接收Date类型数据,须要自定义转换器:Conveter
public class DateConverter implements Converter<String, Date> { @Override public Date convert(String source) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { return simpleDateFormat.parse(source); } catch (ParseException e) { e.printStackTrace(); } return null; } }
配置在springmvc.xml中配置Conveter
<!-- 加载注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 转换器配置 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.kkb.ssm.controller.converter.DateConverter"/>
</set>
</property>
</bean>
自定义异常类,继承Excption;
自定义异常处理类 实现HandlerReceptionResolver;
在springmvc.xml中注册该类便可;
springmvc的上传,是由commons-fileupload这个jar包实现的
文件上出啊须要指定<form>标签的一个属性 : enctype=”multipart/form-data”
在springmvc中配置Multipart解析器
<!-- multipart类型解析器,文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件的最大尺寸 5M-->
<property name="maxUploadSize" value="5242880"/>
</bean>
Controller类:
@RequestMapping(value = "/updateItem") public String updateItem(Model model,Item item,MultipartFile pictureFile) throws Exception { if(pictureFile != null){ System.out.println(pictureFile.getOriginalFilename()); //原始图片名称
String originalFilename = pictureFile.getOriginalFilename(); //若是没有图片名称,则上传不成功
if(originalFilename != null && originalFilename.length()>0) { //存放图片的物理路径
String picPath = "E:\\03-teach\\07-upload\\temp\\"; //新文件的名称
String newFileName = UUID.randomUUID()+originalFilename.substring(originalFilename.lastIndexOf(".")); //新的文件
File newFile = new File(picPath+newFileName); //把上传的文件保存成一个新的文件
pictureFile.transferTo(newFile); //同时须要把新的文件名更新到数据库中
item.setPic(newFileName); }else{ throw new BusinessException("图片名称不存在,上传不成功"); } } // 根据页面传入的商品信息,调用修改方法,进行修改(此时尚未讲参数绑定,暂时没法进行)
itemService.updateItem(item); return "success";
KV结构,请求是Json(通常状况下),@ResponseBody默认响应也是Json 依赖 jackson-databind.jar 固然依赖传递进来的还有一个io.jar
理解:是一种软件架构风格,基于这个风格设计的软件更简洁,更有层次感,Rest指的就是一组架构条件而原则,知足额这个原则设计出来的应用就是Resuful风格
四个表示操做方式的动词: GET 、POST、PUT、DELETE,分别对应四种基本操做
springmvc对RESTful的支持:
web.xml中设置拦截规则为 / ,能够拦截RESTful请求
但也是由于设置了 /,就必须对静态资源进行访问处理
<!-- 当DispatcherServlet配置为/来拦截请求的时候,须要配置静态资源的访问映射 -->
<mvc:resources location=*"/js/"* mapping=*"/js/**"*/> <mvc:resources location=*"/css/"* mapping=*"/css/**"*/>
@PathVariable注解能够解析出URL中的模版变量 以下所示:
请求URL:http://localhost:8080/ssm/item/1/wangbadan
@RequestMapping(" {id} / {name} ")
public void queryItemByIDAndName(@PathVariable Integer id,@PathVariable String name ){}
@RequestMapping注解能够经过method属性,能够将同一个请求映射到不一样的方法上 GET/POST/PUT/DELETE
以致于优化出了如下注解 @GetMapping 、@PostMapping、@PutMapping、@DeleteMapping,效果同上
springmvc有本身的拦截器,实现对请求先后的相关逻辑处理,至关于Servlet的Filter过滤器
springmvc中定义一个Interceptor有一下四种方式:
实现HandlerInterceptor接口,或继承实现了该接口的类 ,好比HandlerInterceptorAdapter
实现Spring的 WebRequestInterceptor接口,或者继承实现了该接口的类
通常经常使用第一种,实现HandlerInterceptor接口,重写
preHandle :Handler执行前执行,好比登陆认证,身份受权,返回Boolean
postHandle :进入Handler,并在返回ModelAndView前执行,通常用于统一指定视图
afterCompletion :执完Handler以后执行,好比异常处理,日志处理,释放资源等
配置拦截器(全局拦截器配置):
<!-- 配置全局mapping的拦截器 -->
<mvc:interceptors>
<!-- 公共拦截器能够拦截全部请求,并且能够有多个 -->
<bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor1" />
<bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor2" />
<!-- 若是有多个拦截器,则按照顺序进行配置 -->
<mvc:interceptor>
<!-- /**表示全部URL和子URL路径 -->
<mvc:mapping path="/test/**" />
<!-- 特定请求的拦截器只能有一个 -->
<bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor3" />
</mvc:interceptor>
</mvc:interceptors>
若是有多个拦截器,则配置到最上面的拦截器的优先级最高
画了个图外加描述理解一下:
Spring和SpringMVC是两个容器;
Spring容器中存放着mapper代理对象,service对象,而SpringMVC中存放的事Controller对象,子容器能够经过@Autowired访问父容器注册过的中的Java实列,反之父容器想注入子容器中的Java实列就不行,好比在service中注入Controller行不通的;
两个容器导入的配置文件,都只能在本身的容器里面使用,不具备传递性
跨域:域名,端口,协议的组合不一样的访问就是跨域
解决跨域的方式有多种:基于Js,基于Jq的JSONP以及基于CORS的方式
JSONP只能解决get方式提交触发的跨域问题,CORS支持多种提交方式
CORS是一个W3C标准,全称:“跨资源共享”,他容许浏览器向跨源服务器发起Ajax请求,克服了Ajax只能同源访问的限制
CORS原理:只须要向响应头header中注入Access-Control-Allow-Origin,这样浏览器检测到header中的Access-Control-Allow-Origin,则就能够跨域操做了。
详情见:http://www.javashuo.com/article/p-xiwekjoe-kc.html
Get提交:
手段一: 修改Tomcat的编码格式为 UTF-8
手段二:对请求参数进行从新编码,String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
Post提交:
手段一:在web.xml中限定编码
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
手段二:在RequestMapping注解中produces属性,指定响应体的编码格式