概述
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 {
}
}
本文深入探讨SpringMVC框架中的HandlerInterceptor接口及其方法:preHandle、postHandle和afterCompletion,解析它们在请求处理过程中的作用及调用时机,帮助开发者理解如何利用这些拦截器优化应用程序。
856

被折叠的 条评论
为什么被折叠?



