Spring Web MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是 AOP思想的具体实现。
区别 | 过滤器 | 拦截器 |
---|---|---|
使用范围 | Servlet 中的一部分,任何 Java Web 工程都可以使用 | Spring Web MVC 框架独有 |
拦截范围 | 配置了 / 全部拦截 | 只会拦截访问控制器方法的请求,*.js 等不会拦截 |
/**
* Created with IntelliJ IDEA.
*
* @author Demo_Null
* @date 2020/8/27
* @description 自定义拦截器
*/
// 实现 HandlerInterceptor 并重写需要的方法
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("在目标方法执行之前执行");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("在目标方法执行之后视图对象返回之前执行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("在流程都执行完毕后执行");
}
}
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 可配置多个拦截器,执行顺序为配置顺序 -->
<mvc:interceptor>
<!-- 拦截的资源路径 -->
<mvc:mapping path="/**"/>
<!-- 指定自定义拦截器 -->
<bean class="com.software.spring.controller.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
/**
* Created with IntelliJ IDEA.
*
* @author Demo_Null
* @date 2020/8/27
* @description 控制器
*/
@RestController
@RequestMapping("/demo")
public class DemoController {
@GetMapping("/get")
public String get() {
System.out.println("请求到了");
return "10086";
}
}
方法将在请求处理之前进行调用,该方法的返回值是布尔值 Boolean 类型的,当它返回为 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当返回值为 true 时就会继续调用下一个 Interceptor 的 preHandle 方法。
该方法是在当前请求进行处理之后被调用,前提是 preHandle 方法的返回值为 true 时才能被调用,且它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作
该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行,前提是 preHandle 方法的返回值为 true 时才能被调用
当拦截器的 preHandle 方法返回 true 则会执行目标资源,如果返回 false 则不执行目标资源;多个拦截器情况下,配置在前的先执行,配置在后的后执行;单个拦截器中的方法执行顺序是:preHandler
☞ 目标资源
☞ postHandle
☞ afterCompletion
;多个拦截器中的方法执行顺序是:preHandler_1
☞ preHandler_2
☞ ···
☞ preHandler_n
☞ 目标资源
☞ postHandle_n
☞ ···
☞ postHandle_2
☞ postHandle_1
☞ afterCompletion_n
☞ ··· ☞ afterCompletion_2
☞ afterCompletion_1