/** * Create a new HandlerExecutionChain. * @param handler the handler object to execute * @param interceptors the array of interceptors to apply * (in the given order) before the handler itself executes */ public HandlerExecutionChain(Object handler, @Nullable HandlerInterceptor... interceptors) { if (handler instanceof HandlerExecutionChain) { HandlerExecutionChain originalChain = (HandlerExecutionChain) handler; this.handler = originalChain.getHandler(); this.interceptorList = new ArrayList<>(); CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList); CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList); } else { this.handler = handler; this.interceptors = interceptors; } }
/** * Update the HandlerExecutionChain for CORS-related handling. * <p>For pre-flight requests, the default implementation replaces the selected * handler with a simple HttpRequestHandler that invokes the configured * {@link #setCorsProcessor}. * <p>For actual requests, the default implementation inserts a * HandlerInterceptor that makes CORS-related checks and adds CORS headers. * @param request the current request * @param chain the handler chain * @param config the applicable CORS configuration (possibly {@code null}) * @since 4.2 */ protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request, HandlerExecutionChain chain, @Nullable CorsConfiguration config) { if (CorsUtils.isPreFlightRequest(request)) { HandlerInterceptor[] interceptors = chain.getInterceptors(); chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors); } else { chain.addInterceptor(new CorsInterceptor(config)); } return chain; }
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); mappedHandler.applyPostHandle(processedRequest, response, mv); mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
/** * Apply preHandle methods of registered interceptors. * @return {@code 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. */ 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]; if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, null); return false; } this.interceptorIndex = i; } } return true; }
/** * Build a handler object for the given raw handler, exposing the actual * handler, the {@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}, as well as * the {@link #URI_TEMPLATE_VARIABLES_ATTRIBUTE} before executing the handler. * <p>The default implementation builds a {@link HandlerExecutionChain} * with a special interceptor that exposes the path attribute and uri template variables * @param rawHandler the raw handler to expose * @param pathWithinMapping the path to expose before executing the handler * @param uriTemplateVariables the URI template variables, can be {@code null} if no variables found * @return the final handler object */ protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern, String pathWithinMapping, @Nullable Map<String, String> uriTemplateVariables) { HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler); chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping)); if (!CollectionUtils.isEmpty(uriTemplateVariables)) { chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables)); } return chain; }
public HandlerExecutionChain mergeInterceptorsToTabs(ProceedingJoinPoint pjp) throws Throwable { HandlerExecutionChain handlerExecutionChain = (HandlerExecutionChain) pjp.proceed(); if (handlerExecutionChain == null) { return null; } return new HandlerExecutionChain(handlerExecutionChain.getHandler(), mergeInterceptors(handlerExecutionChain)); }
/** * Delegates to the handler and interceptors' {@code toString()}. */ @Override public String toString() { Object handler = getHandler(); StringBuilder sb = new StringBuilder(); sb.append("HandlerExecutionChain with [").append(handler).append("] and "); if (this.interceptorList != null) { sb.append(this.interceptorList.size()); } else if (this.interceptors != null) { sb.append(this.interceptors.length); } else { sb.append(0); } return sb.append(" interceptors").toString(); }
/** * Apply postHandle methods of registered interceptors. */ void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable 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); } } }
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(request, response, handler, exception); errorView = (mv != null); mappedHandler.triggerAfterCompletion(request, response, null);
/** * Update the HandlerExecutionChain for CORS-related handling. * <p>For pre-flight requests, the default implementation replaces the selected * handler with a simple HttpRequestHandler that invokes the configured * {@link #setCorsProcessor}. * <p>For actual requests, the default implementation inserts a * HandlerInterceptor that makes CORS-related checks and adds CORS headers. * @param request the current request * @param chain the handler chain * @param config the applicable CORS configuration (possibly {@code null}) * @since 4.2 */ protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request, HandlerExecutionChain chain, CorsConfiguration config) { if (CorsUtils.isPreFlightRequest(request)) { HandlerInterceptor[] interceptors = chain.getInterceptors(); chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors); } else { chain.addInterceptor(new CorsInterceptor(config)); } return chain; }
@Override public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { return new HandlerExecutionChain(new Object()); } }
@Test public void successAsyncScenario() throws Exception { given(this.interceptor1.preHandle(this.request, this.response, this.handler)).willReturn(true); given(this.interceptor2.preHandle(this.request, this.response, this.handler)).willReturn(true); given(this.interceptor3.preHandle(this.request, this.response, this.handler)).willReturn(true); this.chain.applyPreHandle(request, response); this.chain.applyAfterConcurrentHandlingStarted(request, response); this.chain.triggerAfterCompletion(this.request, this.response, null); verify(this.interceptor1).afterConcurrentHandlingStarted(request, response, this.handler); verify(this.interceptor2).afterConcurrentHandlingStarted(request, response, this.handler); verify(this.interceptor3).afterConcurrentHandlingStarted(request, response, this.handler); }
@Test public void successScenario() throws Exception { ModelAndView mav = new ModelAndView(); given(this.interceptor1.preHandle(this.request, this.response, this.handler)).willReturn(true); given(this.interceptor2.preHandle(this.request, this.response, this.handler)).willReturn(true); given(this.interceptor3.preHandle(this.request, this.response, this.handler)).willReturn(true); this.chain.applyPreHandle(request, response); this.chain.applyPostHandle(request, response, mav); this.chain.triggerAfterCompletion(this.request, this.response, null); verify(this.interceptor1).postHandle(this.request, this.response, this.handler, mav); verify(this.interceptor2).postHandle(this.request, this.response, this.handler, mav); verify(this.interceptor3).postHandle(this.request, this.response, this.handler, mav); verify(this.interceptor3).afterCompletion(this.request, this.response, this.handler, null); verify(this.interceptor2).afterCompletion(this.request, this.response, this.handler, null); verify(this.interceptor1).afterCompletion(this.request, this.response, this.handler, null); }
if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; mappedHandler.applyPostHandle(processedRequest, response, mv); mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
@Override public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { HandlerExecutionChain handlerExecutionChain = this.delegate .getHandler(request); if (handlerExecutionChain == null) { return null; } handlerExecutionChain.addInterceptor(this.applicationContext .getBean(SpanCustomizingAsyncHandlerInterceptor.class)); return handlerExecutionChain; }
/** * Retrieve the CORS configuration for the given handler. * @param handler the handler to check (never {@code null}). * @param request the current request. * @return the CORS configuration for the handler, or {@code null} if none * @since 4.2 */ @Nullable protected CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) { Object resolvedHandler = handler; if (handler instanceof HandlerExecutionChain) { resolvedHandler = ((HandlerExecutionChain) handler).getHandler(); } if (resolvedHandler instanceof CorsConfigurationSource) { return ((CorsConfigurationSource) resolvedHandler).getCorsConfiguration(request); } return null; }
private HandlerInterceptor[] mergeInterceptors(HandlerExecutionChain handlerExecutionChain) { HandlerInterceptor[] tabInterceptors = handlerExecutionChain.getInterceptors(); if (tabInterceptors == null) { return interceptorsOfFramework; } HandlerInterceptor[] result = new HandlerInterceptor[interceptorsOfFramework.length + tabInterceptors.length]; System.arraycopy(interceptorsOfFramework, 0, result, 0, interceptorsOfFramework.length); System.arraycopy(tabInterceptors, 0, result, interceptorsOfFramework.length, tabInterceptors.length); return result; }
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); chain.addInterceptor(interceptor);
/** * Apply preHandle methods of registered interceptors. * @return {@code 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. */ 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]; if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, null); return false; } this.interceptorIndex = i; } } return true; }
return new HandlerExecutionChain(requestWrapper, interceptors); return new HandlerExecutionChain(requestWrapper, interceptors); return new HandlerExecutionChain(requestWrapper, interceptors); return new HandlerExecutionChain(requestWrapper, interceptors);