您的位置:首页 > 其它

interceptor的应用与源码分析

2017-05-03 09:01 106 查看
    最近项目中需要用到拦截器,因此研究了一下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);
}
}


    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: