概述
HandlerInterceptor
是Spring MVC
对处理请求的Handler
的拦截处理逻辑的抽象建模接口,该接口定义了三个拦截处理方法供实现类提供实现 :
preHandle
– 前置拦截处理逻辑- 调用时机 :
Handler
调用之前 - 返回值语义
true
– 调用者需要继续调用其它的HandlerInterceptor
/Handler
逻辑false
– 当前请求已经被该方法完全处理,调用者不需要继续其它的HandlerInterceptor
/Handler
逻辑
- 调用时机 :
postHandle
– 后置拦截处理逻辑- 调用时机 :
Handler
调用之后,视图解析和渲染之前 - 无返回值
- 调用时机 :
afterCompletion
– 完成时拦截处理逻辑- 调用时机
- 某个
HandlerInterceptor#preHandle
返回false
时; - 或者
HandlerInterceptor
前置处理,Handler
调用,HandlerInterceptor
后置处理,视图解析和渲染等动作成功完成之后; - 或者
HandlerInterceptor
前置处理,Handler
调用,HandlerInterceptor
后置处理,视图解析和渲染等动作中抛出异常时。
- 某个
- 调用时机
HandlerInterceptor
之对于Handler
的行为类似于Filter
之对于Servlet
。不过HandlerInterceptor
对前置拦截处理逻辑和后置拦截处理逻辑做了分开抽象。Filter
之间传递Request/Response
允许对Request/Response
做包装从而可以传递不同的Request/Response
对象,而HandlerInterceptor
之间传递的Request/Response
对象总是同一个。
在具体使用上 :
HandlerInterceptor
可以由开发人员提供实现,也可能由Spring MVC
框架自身内置提供。Spring MVC
自身内置提供的HandlerInterceptor
例子有ConversionServiceExposingInterceptor
,UserRoleAuthorizationInterceptor
,ResourceUrlProviderExposingInterceptor
等。- 应用启动时,
Spring MVC
配置机制(参考WebMvcConfigurationSupport
)会搜集框架缺省以及开发人员指定的HandlerInterceptor
绑定到bean RequestMappingHandlerMapping requestMappingHandlerMapping
。 - 随后
DispatcherServlet
请求处理主逻辑(#doDispatch
)执行requestMappingHandlerMapping
会被首先用于查找能处理当前请求的Handler
,以HandlerExecutionChain
形式返回,这里的HandlerExecutionChain
就包含了Handler
自身和配置时所加载的HandlerInterceptor
。DispatcherServlet
调用Handler
处理请求,并在Handler
处理请求的前置/后置/完成时生命周期时机调用HandlerExecutionChain
中有关HandlerInterceptor
的拦截器方法逻辑。
这一部分可以参考 :
源代码
源代码版本 Spring Web MVC 5.1.5.RELEASE
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
public interface HandlerInterceptor {
/**
* Handler 执行前置拦截处理逻辑。DispatcherServlet 请求处理主逻辑找到合适的Handler 之后,执行
* Handler 处理请求之前,会先调用相应的 HandlerInterceptor 的该方法。该方法返回 true 表示调用者DispatcherServlet
* 需要继续调用下一个 HandlerInterceptor#preHandle, 或者 Hander。返回 false 表示当前 HandlerInterceptor#preHandle
* 已经对请求进行了处理,调用者DispatcherServlet无需继续对当前请求做进一步处理。
* 该接口中 preHandle 缺省实现是空逻辑,直接返回 true。
* @param request current HTTP request
* @param response current HTTP response
* @param handler chosen handler to execute, for type and/or instance evaluation
* @return true if the execution chain should proceed with the
* next interceptor or the handler itself. Else, DispatcherServlet assumes
* that this interceptor has already dealt with the response itself.
* @throws Exception in case of errors
*/
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
/**
* Handler 执行后置拦截处理逻辑。DispatcherServlet 执行完 Handler 之后,解析和渲染视图之前调用此方法。
* 可以用于通过 ModelAndView 对象 modelAndView 向 view 补充额外的模型数据。注意 postHandle 应用的
* 顺序和 preHandle 的顺序正好相反。
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler (or HandlerMethod) that started asynchronous
* execution, for type and/or instance examination
* @param modelAndView the ModelAndView that the handler returned
* (can also be null}
* @throws Exception in case of errors
*/
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
/**
* 调用者 DispatcherServlet 成功/异常 处理完一个请求(执行Handler,应用postHandle,解析和渲染视图)之后会调用
* 该方法。并不是调用跟对应 Handler 关联的所有的 HandlerInterceptor#afterCompletion,而是仅仅调用那些
* #preHandle调用返回true的HandlerInterceptor的#afterCompletion方法。
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler (or HandlerMethod) that started asynchronous
* execution, for type and/or instance examination
* @param ex exception thrown on handler execution, if any
* @throws Exception in case of errors
*/
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}