一.拦截器简介
1.拦截器概念
拦截器(Interceptor) 是一种用于在请求处理的生命周期中对请求进行拦截的机制。在 Spring MVC 中,拦截器可以在请求到达控制器之前或响应返回给客户端之前对请求和响应做一些处理操作。
2.拦截器作用
拦截器的作用是对请求进行预处理和后处理,它可以执行以下操作:
(1)请求预处理(Pre-processing)
在请求到达控制器之前,拦截器可以进行一些操作,比如记录日志、检查权限、进行参数验证等。它可以决定是否继续执行控制器方法,如果不允许执行,可以直接返回响应或者抛出异常。
(2)请求后处理(Post-processing)
在请求处理完成(即控制器方法执行完毕)后,拦截器可以对响应进行处理,比如修改响应数据、统计性能等。拦截器可以在控制器返回数据之后,进行一些额外的操作,比如修改返回的视图数据、给响应数据添加自定义的字段等。
(3)统一处理
拦截器通常用于一些通用的处理,比如权限校验、日志记录等,避免在每个控制器中都编写重复的代码。
3.执行时机
(1)前置处理(Pre-handle)
(2)控制器方法执行(Controller)
(3)后置处理(Post-handle)
(4)视图渲染(After completion)
二.拦截器入门案例
1.配置方式
(1)通过WebMvcConfigurer实现的配置
这个类实现了WebMvcConfigurer接口,并重写了addInterceptors方法,配置了两个拦截器ProjectInterceptor和ProjectInterceptor2。addPathPatterns方法指定了哪些请求会被拦截,这里是/books路径及其子路径(如/books/1,/books/2等)。
(2)通过WebMvcConfigurationSupport实现的配置
这个类继承自WebMvcConfigurationSupport,同样通过重写addInterceptors来配置拦截器,这种方式相较于WebMvcConfigurer更具侵入性,但它提供了更多的灵活性。
2.具体的拦截器类
(1)ProjectInterceptor类
ProjectInterceptor实现了HandlerInterceptor接口,定义了三个方法:preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):在请求处理之前调用。返回true表示继续执行后续拦截器和控制器方法,返回false表示中止请求。
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):在控制器方法执行后,视图渲染之前调用。此时可以修改ModelAndView对象。
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):在整个请求处理完毕,视图渲染后调用。可以做一些资源清理等工作。
在preHandle方法中,我们获取了请求的Content-Type头部信息,并打印出来。
(2)ProjectInterceptor2类
ProjectInterceptor2与ProjectInterceptor类似,不同之处在于它的preHandle方法返回了false,这意味着请求在执行到控制器方法之前就会被拦截并终止,不会继续执行控制器方法。
3.执行顺序
Spring MVC 中的多个拦截器按配置的顺序执行:
(1)执行顺序:
在请求到达控制器方法之前,拦截器会按照配置顺序执行preHandle方法。
如果其中一个拦截器的preHandle返回false,则后续拦截器的preHandle和控制器方法都不会执行,直接返回响应。
如果所有的preHandle都返回true,则执行控制器方法。
控制器方法执行后,按配置的顺序执行postHandle方法。
最后,执行afterCompletion方法。
(2)多拦截器执行流程
请求到达前:
ProjectInterceptor的preHandle被调用并返回true。ProjectInterceptor2的preHandle被调用并返回false,这会终止请求。
控制器方法未执行:
由于
ProjectInterceptor2的preHandle返回false,控制器方法不会被执行,因此postHandle和afterCompletion也不会被调用。
4.总结
在 Spring MVC 中,拦截器用于在请求处理过程中插入自定义逻辑。拦截器类实现HandlerInterceptor接口,主要包含三个方法:preHandle(请求到达控制器之前),postHandle(控制器方法执行后,视图渲染前),和afterCompletion(整个请求处理完成后)。通过配置类中的addInterceptors方法,多个拦截器可以按照配置顺序依次执行。preHandle方法返回true继续执行请求,返回false则中止请求。拦截器可以用于日志记录、权限验证等场景。多个拦截器的执行顺序是按照注册顺序进行的,且如果某个拦截器的preHandle返回false,后续拦截器和控制器方法将不会执行。