springmvc拦截器 首先这里先区分一下过滤器Filter和拦截器Interceptor,Filter是Servlet中提供的功能,而Interceptor是SpringMVC的
拦截器的使用 Interceptor底层采用的java反射实现的。
在springmvc中使用拦截器,对请求进行拦截处理首先需要实现HandlerInterceptor接口,然后重写该接口中的三个方法
也可以继承HandlerInterceptorAdapter类来重写某个方法
注意:拦截器是springmvc提供的功能,过滤器是javaee中提供的原生功能,过滤器在DispatcherServlet之前执行,拦截器在DispatcherServlet执行过程中调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public interface HandlerInterceptor { boolean preHandle (HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception ; void postHandle (HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception ; void afterCompletion (HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception ; }
然后在配置文件中配置所编写的拦截器
1 2 3 4 5 6 7 <mvc:interceptors > <mvc:interceptor > <mvc:mapping path ="/**" /> <bean class ="com.zhanghe.study.springmvc.interceptor.TestInterceptor" /> </mvc:interceptor > </mvc:interceptors >
在DispatcherServlet的doDispatcher()方法中进行调用,首先会根据映射找到HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)
调用preHandler 1 2 3 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 boolean applyPreHandle (HttpServletRequest request, HttpServletResponse response) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = 0 ; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(request, response, this .handler)) { triggerAfterCompletion(request, response, null ); return false ; } this .interceptorIndex = i; } } return true ; }
调用postHandle 1 mappedHandler.applyPostHandle(processedRequest, response, mv);
1 2 3 4 5 6 7 8 9 10 void applyPostHandle (HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = interceptors.length - 1 ; i >= 0 ; i--) { HandlerInterceptor interceptor = interceptors[i]; interceptor.postHandle(request, response, this .handler, mv); } } }
调用afterCompletion 如果发生异常,也会执行该方法
1 mappedHandler.triggerAfterCompletion(request, response, null );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void triggerAfterCompletion (HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = this .interceptorIndex; i >= 0 ; i--) { HandlerInterceptor interceptor = interceptors[i]; try { interceptor.afterCompletion(request, response, this .handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception" , ex2); } } } }
对于异步请求 1 2 3 4 5 6 if (asyncManager.isConcurrentHandlingStarted()) { if (mappedHandler != null ) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } }
[ ] 由于异步请求是由其他线程直接进行执行的,那么执行了异步请求之后会执行postHandle 和 afterCompletion吗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void applyAfterConcurrentHandlingStarted (HttpServletRequest request, HttpServletResponse response) { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = interceptors.length - 1 ; i >= 0 ; i--) { if (interceptors[i] instanceof AsyncHandlerInterceptor) { try { AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i]; asyncInterceptor.afterConcurrentHandlingStarted(request, response, this .handler); } catch (Throwable ex) { logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted" , ex); } } } } }
拦截器执行顺序 根据上述代码逻辑得出结论:
对于preHandler方法,是按照拦截器配置的顺序执行的
而对于postHadler方法和afterCompletion方法,是按照拦截器配置的反序执行