目录
4.2 拦截器方法说明---详见《自定义拦截器执行流程.png》
3.5 通过BindingResult和form:errors标签在JSP页面显示非验证消息
SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。 依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于 web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个 controller生命周期之内可以多次调用。
依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例 只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码; 在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。
过滤器(filter): 1) filter属于Servlet技术,只要是web工程都可以使用 2) filter主要对所有请求过滤 3) filter的执行时机早于Interceptor 拦截器(interceptor) 1) interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用 2) interceptor通常对处理器Controller进行拦截 3) interceptor只能拦截dispatcherServlet处理的请求
1)日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
2)权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;
3)性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4)通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。
创建HelloController 创建自定义拦截器并实现HandlerInterceptor接口。
<mvc:interceptors>
<bean class="com.zking.springmvc07.interceptor.CustomInterceptor"/>
</mvc:interceptors>
作用:用于对拦截到的请求进行预处理,方法接收布尔(true,false)类型的返回值,返回true:放行,false:不放行。 执行时机:在处理器方法执行前执行
方法参数: 1)request请求对象 2)response响应对象 3)handler拦截到的方法处理
作用:用于对拦截到的请求进行后处理,可以在方法中对模型数据和视图进行修改 执行时机:在处理器的方法执行后,视图渲染之前
方法参数: 1)request请求对象 2)response响应对象 3)handler拦截到的处理器方法 4)ModelAndView处理器方法返回的模型和视图对象,可以在方法中修改模型和视图
作用:用于在整个流程完成之后进行最后的处理,如果请求流程中有异常,可以在方法中获取对象 执行时机:视图渲染完成后(整个流程结束之后)
方法参数: 1)request请求参数 2)response响应对象 3)handler拦截到的处理器方法 4)ex异常对象
拦截器链的概念:如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链,主要理解拦截器链中各个拦截器的执行顺序。拦截器链中多个拦截器的执行顺序,根拦截器的配置顺序有关,先配置的先执行。
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.zking.springmvc07.interceptor.CustomInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/**"/>
<bean class="com.zking.springmvc07.interceptor.Custom2Interceptor"/>
</mvc:interceptor>
</mvc:interceptors>
JSR303是Java为Bean数据合法性校验提供给的标准框架,已经包含在 JavaEE6.0中、JSR303通过在Bean 属性中标注类似 @NotNull @Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean进行验证
JSR303属于后端验证 JS属于前端的脚本验证(只作用于客户端的浏览器中,可以被屏蔽) 技术点:正则表达式 直接浏览器地址栏回车、借助于第三方的工具(PostMan)
@Null 被注释的元素必须为 null @NotNull 被注释的元素必须不为 null @AssertTrue 被注释的元素必须为 true @AssertFalse 被注释的元素必须为 false @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 @Size(max=, min=) 被注释的元素的大小必须在指定的范围内 @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内 @Past 被注释的元素必须是一个过去的日期 @Future 被注释的元素必须是一个将来的日期 @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
@NotBlank(message =) 验证字符串非null,且长度必须大于0 @Email 被注释的元素必须是电子邮箱地址 @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内 @NotEmpty 被注释的字符串的必须非空 @Range(min=,max=,message=) 被注释的元素必须在合适的范围内
注:Hibernate Validator是JSR303的一个参考实现,除了支持所有标准的校验注解外,另外Hibernate Validator还有JSR-380的实现
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
public class User {
private Long userId;
@NotBlank(message = "用户名不能为空")
private String userName;
@NotBlank(message = "密码不能为空")
private String userPwd;
............
}
public String login(@Validated @ModelAttribute User user,
BindingResult bindingResult){
// 服务器端校验不通过
if (bindingResult.hasErrors()) {
return "login";
}
....
}
注1:@Valid和Validated的区别,随便使用哪个都行 @Valid是使用hibernate validation的时候使用 @Validated 是只用spring Validator校验机制使用
<form:errors path="*" /> 显示表单所有错误
<form:errors path="user* /> 显示所有以user为前缀的属性对应的错误
<form:errors path="username"/> 显示特定表单对象属性的错误
delimiter:如果一个属性有多个错误,错误信息的分隔符。默认是换行
注1:errors标签要放到form标签中才能显示错误消息 注2:如果使用form:errors标签不显示错误消息,请检查Model中是否已经添加了命令对象,没有是不会显示错误消息的 注3:注意命名规范,Book-->book
@ModelAttribute
public void init(Model model) {
System.out.println("init...");
model.addAttribute("user", new User());
}
public String login(@Valid @ModelAttribute Yh yh, BindingResult bindingResult, Model model){
bindingResult.rejectValue("yhzh", null, "帐号错误");
...
}
bindingResult.rejectValue("email", "validate.email.empty", "邮箱不能为空");//这个函数有好几个重载的变体
它们是可以支持国际化的。 比如,上面这个例子表示, 错误的字段(filed)是“email”, errorCode是“validate.email.empty”, 与资源文件对应, 第三个是defaultMessage