springMVC之Interceptor拦截器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25673113/article/details/79153547

Interceptor拦截器用于拦截Controller层接口,表现形式有点像Spring的AOP,但是AOP是针对单一的方法。Interceptor是针对Controller接口以及可以处理request和response对象。

1 HandlerInterceptor接口的定义

我们先来看下HandlerInterceptor接口的定义,定义了三个接口,分别是preHandle、postHandle、afterCompletion。

public interface HandlerInterceptor {

    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;

    void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception;

    void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception;

}

preHandle是调用Controller之前被调用,当返回false后,会跳过之后的拦截器,并且不会执行所有拦截器的postHandle,并调用返回true的拦截器的afterCompletion方法。
postHandle是调用Controller之后被调用,但是在渲染View页面之前。
afterCompletion是调用完Controller接口,渲染View页面最后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法,顺序相反。

和HandlerInterceptor很相似的要有一个AsyncHandlerInterceptor接口,只是多了个afterConcurrentHandlingStarted个方法,当接口使用了异步的方法的时候调用。

public interface AsyncHandlerInterceptor extends HandlerInterceptor {

    void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;

}

2 HandlerInterceptor接口的定义

2.1 DispatcherServlet里doDispatch主处理逻辑

DispatcherServlet里doDispatch()就是springMVC的处理主要逻辑。因此肯定包含了拦截器的主要处理逻辑

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {

            try {
                //.......省略代码

                //返回HandlerExecutionChain  其中包含了拦截器队列
                mappedHandler = getHandler(processedRequest);

                //调用拦截器PreHandle方法,若返回false不执行Controller逻辑,并不调用下面的PostHandle方法
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // 处理Controller层
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                applyDefaultViewName(processedRequest, mv);

                //调用拦截器的PostHandle方法
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }

            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        catch (Exception ex) {
            //抛出异常后都会调用拦截器AfterCompletion方法
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                // Instead of postHandle and afterCompletion
                if (mappedHandler != null) {
                    //若Controller方法为异步调用,则执行拦截器afterConcurrentHandlingStarted(只有AsyncHandlerInterceptor拦截器才有)
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            }
        }
    }

2.2 获取拦截器

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //返回HandlerExecutionChain  其中包含了拦截器队列
    mappedHandler = getHandler(processedRequest);
}
//返回HandlerExecutionChain
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

    HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
    return executionChain;
}

protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
                (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

        //根据url和拦截器异常的配置url做对比,若符合则加入队列
        String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
        for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
            if (interceptor instanceof MappedInterceptor) {
                MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
                if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
                    chain.addInterceptor(mappedInterceptor.getInterceptor());
                }
            }
            else {
                chain.addInterceptor(interceptor);
            }
        }
        return chain;
}

public boolean matches(String lookupPath, PathMatcher pathMatcher) {
        PathMatcher pathMatcherToUse = (this.pathMatcher != null) ? this.pathMatcher : pathMatcher;
        if (this.excludePatterns != null) {
            for (String pattern : this.excludePatterns) {
                if (pathMatcherToUse.match(pattern, lookupPath)) {
                    return false;
                }
            }
        }
        if (this.includePatterns == null) {
            return true;
        }
        else {
            for (String pattern : this.includePatterns) {
                if (pathMatcherToUse.match(pattern, lookupPath)) {
                    return true;
                }
            }
            return false;
        }
}

上述的拦截器的信息,都来自与下面的配置文件

<!-- 拦截器链 -->
    <mvc:interceptors>

        <mvc:interceptor>
            <!--拦截器mapping 符合的才会执行拦截器-->
            <mvc:mapping path="/**"/>
            <!--在拦截器mapping中除去下面的url -->
            <mvc:exclude-mapping path="/transactional_test/*"/>
            <!--执行的拦截器-->
            <ref bean="apiInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

    <bean id="apiInterceptor" class="com.lk.dome.interceptor.ApiInterceptor"/>

2.3 处理拦截器

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];
                //若返回false,则直接执行拦截器的triggerAfterCompletion方法
                if (!interceptor.preHandle(request, response, this.handler)) {
                    triggerAfterCompletion(request, response, null);
                    //直接返回,在外层的doDispatch逻辑中不执行后面的逻辑
                    return false;
                }
                //记录成功执行的拦截器个数
                this.interceptorIndex = i;
            }
        }
        return true;
}
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);
            }
        }
}
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)
            throws Exception {

        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            //interceptorIndex为执行成功的拦截器标志
            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);
                }
            }
        }
}
//异步方法调用,拦截器必须属于AsyncHandlerInterceptor接口
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);
                    }
                }
            }
        }
}

猜你喜欢

转载自blog.csdn.net/qq_25673113/article/details/79153547