Spring MVC是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架。它与Struts2框架一样,都属于MVC框架,但其使用和性能等方面比Struts2更加优异。
是Spring框架的一部分,可以方便的利用Spring所提供的其他功能。
灵活性强,易于与其他框架集成。
提供了一个前端控制器DispatcherServlet,使开发人员无需额外开发控制器对象。
可自动绑定用户输入,并能正确的转换数据类型。
内置了常见的校验器,可以校验用户输入。如果校验不能通过,那么就会重定向到输入表单。
支持国际化。可以根据用户区域显示多国语言。
支持多种视图技术。它支持JSP、Velocity和FreeMarker等视图技术。
web.xml种配置作用:SpringWeb应用程序的前端控制器,负责处理所有应用程序请求
1、用户通过浏览器向服务器发送请求,请求会被Spring MVC的前端控制器DispatcherServlet所拦截;
2、DispatcherServlet拦截到请求后,会调用HandlerMapping处理器映射器;
3、处理器映射器根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
4、DispatcherServlet会通过返回信息选择合适的HandlerAdapter(处理器适配器);
5、HandlerAdapter会调用并执行Handler(处理器),这里的处理器指的就是程序中编写的Controller类,也被称之为后端控制器;
6、Controller执行完成后,会返回一个ModelAndView对象,该对象中会包含视图名或包含模型和视图名;
7、HandlerAdapter将ModelAndView对象返回给DispatcherServlet;
8、DispatcherServlet会根据ModelAndView对象选择一个合适的ViewReslover(视图解析器);
9、ViewReslover解析后,会向DispatcherServlet中返回具体的View(视图);
10、DispatcherServlet对View进行渲染(即将模型数据填充至视图中);
11、视图渲染结果会返回给客户端浏览器显示。
1、/*
的意思是“所有的请求”
/
的意思是“所有的末被其它servlets接收并处理的请求”
2、在DispatcherServlet中,如果用了 /*
,那么就会处理所有的请求,这意味着也会比JSP servlet优先处理.jsp请求。所以这也是为什么在DispacherServlet中通常配置的是
。通常情况下,只有在Filter中才会使用 /*
,这样可以监听所有的request请求
3、若将 DispatcherServlet 请求映射配置为 /, 则 Spring MVC 将捕获 WEB 容器的所有请求
, 包括静态资源的请求(如加入的JQuery), SpringMVC 会将他们当成一个普通请求处理, 因找不到对应处理器将导致错误。
4、解决:
在 SpringMVC 的配置文件中配置
。配置后,原来的请求又会出现问题,需要配置
Spring通过@Controller
注解找到相应的控制器类后,还需要知道控制器内部对每一个请求是如何处理的,这就需要使用@RequestMapping
注解类型,它用于映射一个请求或一个方法。使用时,可以标注在一个方法或
一个类上。
1、 标注在方法上:作为请求处理方法在接收到对应的URL请求时被调用: 其中value也可以使用path代替
2、 标注在类上:该类中的所有方法都将映射为相对于类级别的请求,表示该控制器所处理的所有请求都被映射到value属性值所指定的路径下。
请求方法共有:
——@GetMapping
——@PostMapping
——@PutMapping
——@DeleteMapping
可用于REST(Representational State Transfer)
风格编程
HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
示例:
——/order/1 HTTP GET :得到 id = 1 的 order
——/order/1 HTTP DELETE:删除 id = 1的 order
——/order/1 HTTP PUT:更新id = 1的 order
——/order HTTP POST:新增 order
在数据绑定过程中,Spring MVC框架会通过数据绑定组件(DataBinder)将请求参数串的内容进行类型转换,然后将转换后的值赋给控制器类中方法的形参,这样后台方法就可以正确绑定并获取客户端请求携带的参数了。接下来,将通过一张数据流程图来介绍数据绑定的过程。
1、Spring MVC将ServletRequest对象传递给DataBinder;
2、将处理方法的入参对象传递给DataBinder;
3、DataBinder调用ConversionService组件进行数据类型转换、数据格式化等工作,并将ServletRequest对象中的消息填充到参数对象中;
4、调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验;
5、校验完成后会生成数据绑定结果BindingResult对象,Spring MVC会将BindingResult对象中的内容赋给处理方法的相应参数。
@RequestParam获取请求参数
@CookieValue获取cookie
使用POJO获取参数
使用 Servlet API 作为入参
@PathVariable
可以使用Spring MVC提供的@RequestParam注解类型来进行数据绑定。
在实际应用中,客户端请求可能会传递多个不同类型的参数数据,如果还使用简单数据类型进行绑定,那么就需要手动编写多个不同类型的参数,这种操作显然比较繁琐。
当前端请求的参数比较简单时,可以在后台方法的形参中直接使用Spring MVC提供的默认参数类型进行数据绑定。
在发送REST风格的请求
或URL的路径中带有参数
时,可以通过@PathVariable获取相关参数。
Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。
Spring MVC 在调用目标处理方法前,会先
逐个调用在方法级上标注了@ModelAttribute 的方法。
存在问题:没有准备模型数据时,可能会篡改原有的数据信息,导致一些不需要修改的信息也被修改
解决方案:准备模型数据
可以从隐含对象中获取隐含的模型数据,再与请求参数 绑定
将方法入参对象添加到模型中
String类型除了可以返回上述代码中的视图页面外,还可以进行重定向与请求转发,具体方式如下:
1.redirect 重定向。例如,在修改用户信息操作后,将请求重定向到用户查询方法的实现代码如下:
@RequestMapping(value="/update")
public String update(HttpServletRequest request,HttpServletResponse response, Model model){
...
return "redirect:queryUser";
}
2.forward 请求转发。例如,用户执行修改操作时,转发到用户修改页面的实现代码如下:
@RequestMapping(value="/toEdit")
public String update(HttpServletRequest request,HttpServletResponse response, Model model){
...
return "forward:editUser";
}
Spring MVC框架的Converter
是一个可以将一种数据类型转换成另一种数据类型的接口,这里S表示源类型,T表示目标类型。
开发者在实际应用中,使用框架内置的类型转换器基本就够了,但有时需要编写具有特定功能的类型转换器。
Spring MVC框架的Formatter
与Converter
一样,也是一个可以将一种数据类型转换成另一种数据类型的接口。但不同的是,Formatter
的源数据类型必须是String类型,而Converter
的源数据类型是任意数据类型。
在Web应用中,由HTTP发送的请求数据到控制器中都是以String类型获取。因此,在Web应用中选择Formatter
比选择Converter
更加合理。
1、字符串到Goods类的数据转换
例如将格式为字符串”name;price;amount”转换为一个Goods对象
2、日期数据格式化
例如将格式为”yyyy-mm-dd”日期格式化为Date类型
数据验证分为客户端验证和服务器端验证,客户端验证主要是过滤正常用户的误操作,主要通过JavaScript代码完成;服务器端验证是整个应用阻止非法数据的最后防线,主要通过在应用中编程实现。
JSR 303验证
是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是Hibernate Validator。
注意Hibernate Validator和Hibernate无关,只是使用它进行数据验证。
Hibernate Validator
空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
Booelan检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) Validates that the annotated string is between min and max included.
日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前,验证成立的话被注释的元素一定是一个过去的日期
@Future 验证 Date 和 Calendar 对象是否在当前时间之后 ,验证成立的话被注释的元素一定是一个将来的日期
@Pattern 验证 String 对象是否符合正则表达式的规则,被注释的元素符合制定的正则表达式,regexp:正则表达式 flags: 指定 Pattern.Flag 的数组,表示正则表达式的相关选项。
邮件地址检查
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
数值检查
@Min 验证 Number 和 String 对象是否大等于指定的值
@Max 验证 Number 和 String 对象是否小等于指定的值
@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits 验证 Number 和 String 的构成是否合法
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
@Range(min=, max=) 被指定的元素必须在合适的范围内
数据校验:
导入Hibernate Validator所需jar
使用注解对bean的属性定义验证约束
定义错误消息资源文件
使用@Valid注解进行数据验证
显示错误消息
配置SpringMVC,添加validator
modelAttribute=“staff” 对应controller的模型数据
使用@Valid注解进行数据验证
Spring MVC的拦截器(Interceptor)与Java Servlet的过滤器(Filter)类似,它主要用于拦截用户的请求并做相应的处理。通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。
实现HandlerInterceptor接口,并实现接口中的三个方法。有关这三个方法的描述如下。
1、preHandle()方法:该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作。返回true表示继续向下执行,返回false表示中断后续操作。
2、postHandle()方法:该方法在控制器的处理请求方法调用之后,解析视图之前执行。可以通过此方法对请求域中的模型和视图做进一步的修改。
3、afterCompletion()方法:该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行。可以通过此方法实现一些资源清理等工作。
程序首先将执行拦截器类中的preHandle()方法,如果该方法返回true,程序将继续执行控制器中处理请求的方法,否则中断执行。
如果preHandle()方法返回true,并且控制器中处理请求的方法执行后返回视图前,将执行postHandle()方法。
返回视图后,才执行afterCompletion()方法。
在Web应用中,通常有多个拦截器同时工作,这时它们的preHandle()方法将按照配置文件中拦截器的配置顺序执行,而它们的postHandle()方法和afterCompletion()方法则按照配置顺序的反序执行。
异常处理
文件上传与下载
国际化等