Spring MVC : 概念模型 HandlerInterceptor

概述

HandlerInterceptorSpring 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对象总是同一个。

在具体使用上 :

  1. HandlerInterceptor可以由开发人员提供实现,也可能由Spring MVC框架自身内置提供。Spring MVC自身内置提供的HandlerInterceptor例子有ConversionServiceExposingInterceptor,UserRoleAuthorizationInterceptor,ResourceUrlProviderExposingInterceptor等。
  2. 应用启动时,Spring MVC配置机制(参考WebMvcConfigurationSupport)会搜集框架缺省以及开发人员指定的HandlerInterceptor绑定到bean RequestMappingHandlerMapping requestMappingHandlerMapping
  3. 随后DispatcherServlet请求处理主逻辑(#doDispatch)执行
    1. requestMappingHandlerMapping会被首先用于查找能处理当前请求的Handler,以HandlerExecutionChain形式返回,这里的HandlerExecutionChain就包含了Handler自身和配置时所加载的HandlerInterceptor
    2. 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 {
	}

}

参考文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值