目录
- JSR303
- 拦截器
服务端的验证
- <dependency>
-
- <groupId>org.hibernategroupId>
-
- <artifactId>hibernate-validatorartifactId>
-
- <version>6.0.7.Finalversion>
-
- dependency>
- package com.ps.ssm.model;
-
- import javax.validation.constraints.NotBlank;
- import javax.validation.constraints.NotNull;
-
- /**
- * @NotNull :作用于基本数据类型
- * @NotEmpty 作用于集合
- * @NotBlank 作用于字符串
- */
- public class Clazz {
- @NotNull(message = "班级编号不能为空")
- // @Size(max = 100,min = 10,message = "大小必须在10至100之间")
- protected Integer cid;
-
- @NotBlank(message = "班级名不能为空")
- protected String cname;
-
- @NotBlank(message = "班级教员老师不能为空")
- protected String cteacher;
-
- protected String pic;
-
- public Clazz(Integer cid, String cname, String cteacher, String pic) {
- this.cid = cid;
- this.cname = cname;
- this.cteacher = cteacher;
- this.pic = pic;
- }
-
- public Clazz() {
- super();
- }
- // 给数据添加服务端校验
- @RequestMapping("/valiAdd")
- public String valiAdd(@Validated Clazz clazz, BindingResult result,HttpServletRequest req){
- // 如果服务端验证不通过,有错误
- if(result.hasErrors()){
- // 服务端验证了实体类的多个属性,多个属性都没有验证通过
- List
fieldErrors = result.getFieldErrors(); - Map
map = new HashMap<>(); - for (FieldError fieldError : fieldErrors) {
- // 将多个属性的验证失败信息输送到控制台
- System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
- map.put(fieldError.getField(),fieldError.getDefaultMessage());
- }
- req.setAttribute("errorMap",map);
- }else {
- this.clazzBiz.insertSelective(clazz);
- return "redirect:/clz/list";
- }
- return "clzEdit";
- }
- <body>
- <%--<form action="${pageContext.request.contextPath }/clz/${empty b ? 'add' : 'edit'}" method="post">--%>
- <form action="${pageContext.request.contextPath }/clz/${empty b ? 'valiAdd' : 'edit'}" method="post">
- id:<input type="text" name="cid" value="${b.cid }"><span style="color: red;">${errorMap.cid}span><br>
- cname:<input type="text" name="cname" value="${b.cname }"><span style="color: red;">${errorMap.cname}span><br>
- cteacher:<input type="text" name="cteacher" value="${b.cteacher }"><span style="color: red;">${errorMap.cteacher}span><br>
- <input type="submit">
- form>
- body>
- SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
- 依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于
- web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个
- controller生命周期之内可以多次调用。
- 依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例
- 只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码;
- 在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。
过滤器(filter):
- filter属于Servlet技术,只要是web工程都可以使用
- filter主要对所有请求过滤
- filter的执行时机早于Interceptor
拦截器(interceptor):
- interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用
- interceptor通常对处理器Controller进行拦截
- interceptor只能拦截dispatcherServlet处理的请求
- 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
- 权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;
- 性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前 记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
- 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。
写一个类 创建HelloController,创建自定义拦截器并实现HandlerInterceptor接口。
- @Controller
- public class HelloController {
- @RequestMapping("/hello")
- public String hello(){
- System.out.println("come in hello.jsp");
- return "index";
- }
- }
-
-
- public class OneInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- System.out.println("【OneInterceptor】:preHandle...");
-
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("【OneInterceptor】:postHandle...");
-
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("【OneInterceptor】:afterCompletion...");
- }
- }
- <mvc:interceptors>
- <bean class="com.ps.ssm.interceptor.OneInterceptor">bean>
- mvc:interceptors>
OneHandlerInterceptor
- package com.ps.ssm.intercept;
-
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
-
- public class OneHandlerInterceptor implements HandlerInterceptor {
-
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- //预处理
- System.out.println("【OneInterceptor】:preHandle...");
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- //后处理
- System.out.println("【OneInterceptor】:postHandle...");
-
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- //完成后执行
- System.out.println("【OneInterceptor】:afterCompletion...");
- }
-
- }
运行:


概念:
如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链,主要理解拦截器链中各个拦截器的执行顺序。
拦截器链中多个拦截器的执行顺序,根拦截器的配置顺序有关,先配置的先执行。
springmvc-servlet.xml
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <bean class="com.ps.ssm.intercept.OneHelloController">bean>
- mvc:interceptor>
- <mvc:interceptor>
- <mvc:mapping path="/clz/**"/>
- <bean class="com.ps.ssm.intercept.TwoHelloController">bean>
- mvc:interceptor>
- mvc:interceptors>
TwoHandlerInterceptor.java
- package com.ps.ssm.intercept;
-
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- /**
- * @author 彭于晏
- * @site www.yuyuan.com
- * @create 2022-08-20 00:49
- */
- public class TwoHandlerInterceptor implements HandlerInterceptor {
-
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- //预处理
- System.out.println("【TwoHandlerInterceptor】:preHandle...");
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- //后处理
- System.out.println("【TwoHandlerInterceptor】:postHandle...");
-
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- //完成后执行
- System.out.println("【TwoHandlerInterceptor】:afterCompletion...");
- }
-
- }
测试步骤如下:
http://localhost:8080/clz/list 不能访问,因为session被过滤掉
http://localhost:8080/login 不能访问,因为用户未成功登录被过滤掉
http://localhost:8080/login?uname=zs 可以访问
http://localhost:8080/logout 清除掉session
输入 http://localhost:8080/login?uname=zs 的测试结果:

今天的分享就到这里,我们下次再见!