interceptor的应用与源码分析

来源:互联网 发布:电信网络经常掉线 编辑:程序博客网 时间:2024/06/05 20:19

    最近项目中需要用到拦截器,因此研究了一下interceptor。interceptor是针对方法的拦截。

1 interceptor的应用

    1.1 定义Interceptor

public class InterceptorTest extends HandlerInterceptorAdapter {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)        throws Exception {        System.out.println("preHandle in InterceptorTest");        return super.preHandle(request, response, handler);    }    @Override    public void postHandle(        HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)        throws Exception {        System.out.println("postHandle in InterceptorTest");    }    @Override    public void afterCompletion(        HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)        throws Exception {        System.out.println("afterCompletion in InterceptorTest");    }}

    实现方式有两种一种是如上所示继承HandleInterceptorAdapter接口,另一种是实现HandleInterceptor接口,两种方式都可以

    1.2 定义xml文件

    <mvc:interceptors>        <mvc:interceptor>            <mvc:mapping path="/**"/>            <bean class="test.interceptor.interceptorTest" />        </mvc:interceptor>    </mvc:interceptors>

    <mvc:mapping path="">为拦截器的拦截范围,<mvc:exclude-mapping path="">为拦截器的不被拦截范围

2 interceptor的原理

    我们看DispatcherServlet方法中的doDispatch方法,看源码可以知道:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;int interceptorIndex = -1;try {ModelAndView mv;boolean errorView = false;try {processedRequest = checkMultipart(request);// Determine handler for the current request.mappedHandler = getHandler(processedRequest, false);if (mappedHandler == null || mappedHandler.getHandler() == null) {noHandlerFound(processedRequest, response);return;}// Determine handler adapter for the current request.HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());                // Process last-modified header, if supported by the handler.String method = request.getMethod();boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if (logger.isDebugEnabled()) {String requestUri = urlPathHelper.getRequestUri(request);logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);}if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}// Apply preHandle methods of registered interceptors.HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();if (interceptors != null) {for (int i = 0; i < interceptors.length; i++) {HandlerInterceptor interceptor = interceptors[i];if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);return;}interceptorIndex = i;}}// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());// Do we need view name translation?if (mv != null && !mv.hasView()) {mv.setViewName(getDefaultViewName(request));}// Apply postHandle methods of registered interceptors.if (interceptors != null) {for (int i = interceptors.length - 1; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);}}}catch (ModelAndViewDefiningException ex) {logger.debug("ModelAndViewDefiningException encountered", ex);mv = ex.getModelAndView();}catch (Exception ex) {Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);mv = processHandlerException(processedRequest, response, handler, ex);errorView = (mv != null);}// Did the handler return a view to render?if (mv != null && !mv.wasCleared()) {render(mv, processedRequest, response);if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}else {if (logger.isDebugEnabled()) {logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +"': assuming HandlerAdapter completed request handling");}}// Trigger after-completion for successful outcome.triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);}catch (Exception ex) {// Trigger after-completion for thrown exception.triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);throw ex;}catch (Error err) {ServletException ex = new NestedServletException("Handler processing failed", err);// Trigger after-completion for thrown exception.triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);throw ex;}finally {// Clean up any resources used by a multipart request.if (processedRequest != request) {cleanupMultipart(processedRequest);}}}

    首先会执行getHandler方法,生成HandlerExecutionChain,其中包括handler和interceptorList,在真正通过handlerAdapter执行handler方法之前会遍历interceptor执行preHandle方法,如下所示
if (interceptors != null) {for (int i = 0; i < interceptors.length; i++) {HandlerInterceptor interceptor = interceptors[i];if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);return;}interceptorIndex = i;}}
    执行结束后会执行postHandle方法:
// Apply postHandle methods of registered interceptors.if (interceptors != null) {for (int i = interceptors.length - 1; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);}}

    
0 0
原创粉丝点击