/** * 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); } } }
/** * Apply afterConcurrentHandlerStarted callback on mapped AsyncHandlerInterceptors. */ 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); } } } } }
/** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors. * Will just invoke afterCompletion for all interceptors whose preHandle invocation * has successfully completed and returned true. */ void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { 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); } } } }
/** * 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; }
/** * 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; } }
@Override @Nullable public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { Assert.notNull(this.handlerMappings, "Handler mappings not initialized"); HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request); for (HandlerMapping handlerMapping : this.handlerMappings) { HandlerExecutionChain handler = null; try { handler = handlerMapping.getHandler(wrapper); } catch (Exception ex) { // Ignore } if (handler == null) { continue; } if (handler.getInterceptors() != null) { for (HandlerInterceptor interceptor : handler.getInterceptors()) { if (interceptor instanceof CorsConfigurationSource) { return ((CorsConfigurationSource) interceptor).getCorsConfiguration(wrapper); } } } if (handler.getHandler() instanceof CorsConfigurationSource) { return ((CorsConfigurationSource) handler.getHandler()).getCorsConfiguration(wrapper); } } return null; }
@Override protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { HandlerExecutionChain chain = super.getHandler(request); if (chain != null) { DefaultMvcResult mvcResult = getMvcResult(request); mvcResult.setHandler(chain.getHandler()); mvcResult.setInterceptors(chain.getInterceptors()); } return chain; }
@Test public void beanNameHandlerMapping() throws Exception { ApplicationContext context = initContext(WebConfig.class); BeanNameUrlHandlerMapping handlerMapping = context.getBean(BeanNameUrlHandlerMapping.class); assertEquals(2, handlerMapping.getOrder()); HttpServletRequest request = new MockHttpServletRequest("GET", "/testController"); HandlerExecutionChain chain = handlerMapping.getHandler(request); assertNotNull(chain); assertNotNull(chain.getInterceptors()); assertEquals(3, chain.getInterceptors().length); assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[1].getClass()); assertEquals(ResourceUrlProviderExposingInterceptor.class, chain.getInterceptors()[2].getClass()); }
/** * 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; }
private HandlerExecutionChain getHandler(MockHttpServletRequest req) throws Exception { HandlerExecutionChain hec = hm.getHandler(req); HandlerInterceptor[] interceptors = hec.getInterceptors(); if (interceptors != null) { for (HandlerInterceptor interceptor : interceptors) { interceptor.preHandle(req, null, hec.getHandler()); } } return hec; }
private CorsConfiguration getCorsConfiguration(HandlerExecutionChain chain, boolean isPreFlightRequest) { if (isPreFlightRequest) { Object handler = chain.getHandler(); assertTrue(handler.getClass().getSimpleName().equals("PreFlightHandler")); DirectFieldAccessor accessor = new DirectFieldAccessor(handler); return (CorsConfiguration)accessor.getPropertyValue("config"); } else { HandlerInterceptor[] interceptors = chain.getInterceptors(); if (interceptors != null) { for (HandlerInterceptor interceptor : interceptors) { if (interceptor.getClass().getSimpleName().equals("CorsInterceptor")) { DirectFieldAccessor accessor = new DirectFieldAccessor(interceptor); return (CorsConfiguration) accessor.getPropertyValue("config"); } } } } return null; }
private HandlerExecutionChain getHandler(HandlerMapping hm, MockHttpServletRequest req) throws Exception { HandlerExecutionChain hec = hm.getHandler(req); HandlerInterceptor[] interceptors = hec.getInterceptors(); if (interceptors != null) { for (HandlerInterceptor interceptor : interceptors) { interceptor.preHandle(req, null, hec.getHandler()); } } return hec; }
private CorsConfiguration getCorsConfiguration(HandlerExecutionChain chain, boolean isPreFlightRequest) { if (isPreFlightRequest) { Object handler = chain.getHandler(); assertTrue(handler.getClass().getSimpleName().equals("PreFlightHandler")); DirectFieldAccessor accessor = new DirectFieldAccessor(handler); return (CorsConfiguration)accessor.getPropertyValue("config"); } else { HandlerInterceptor[] interceptors = chain.getInterceptors(); if (interceptors != null) { for (HandlerInterceptor interceptor : interceptors) { if (interceptor.getClass().getSimpleName().equals("CorsInterceptor")) { DirectFieldAccessor accessor = new DirectFieldAccessor(interceptor); return (CorsConfiguration) accessor.getPropertyValue("config"); } } } } return null; }
@Test public void testBeanDecoration() throws Exception { loadBeanDefinitions("mvc-config-bean-decoration.xml"); RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class); assertNotNull(mapping); mapping.setDefaultHandler(handlerMethod); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); HandlerExecutionChain chain = mapping.getHandler(request); assertEquals(3, chain.getInterceptors().length); assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor); assertTrue(chain.getInterceptors()[1] instanceof LocaleChangeInterceptor); assertTrue(chain.getInterceptors()[2] instanceof ThemeChangeInterceptor); LocaleChangeInterceptor interceptor = (LocaleChangeInterceptor) chain.getInterceptors()[1]; assertEquals("lang", interceptor.getParamName()); ThemeChangeInterceptor interceptor2 = (ThemeChangeInterceptor) chain.getInterceptors()[2]; assertEquals("style", interceptor2.getParamName()); }
@Test public void testInterceptors() throws Exception { loadBeanDefinitions("mvc-config-interceptors.xml"); RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class); assertNotNull(mapping); mapping.setDefaultHandler(handlerMethod); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); request.setRequestURI("/accounts/12345"); request.addParameter("locale", "en"); request.addParameter("theme", "green"); HandlerExecutionChain chain = mapping.getHandler(request); assertEquals(4, chain.getInterceptors().length); assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor); assertTrue(chain.getInterceptors()[1] instanceof LocaleChangeInterceptor); assertTrue(chain.getInterceptors()[2] instanceof ThemeChangeInterceptor); assertTrue(chain.getInterceptors()[3] instanceof UserRoleAuthorizationInterceptor); request.setRequestURI("/admin/users"); chain = mapping.getHandler(request); assertEquals(2, chain.getInterceptors().length); request.setRequestURI("/logged/accounts/12345"); chain = mapping.getHandler(request); assertEquals(3, chain.getInterceptors().length); request.setRequestURI("/foo/logged"); chain = mapping.getHandler(request); assertEquals(3, chain.getInterceptors().length); }
@Test public void orderedInterceptors() throws Exception { HandlerInterceptor i1 = Mockito.mock(HandlerInterceptor.class); MappedInterceptor mappedInterceptor1 = new MappedInterceptor(new String[]{"/**"}, i1); HandlerInterceptor i2 = Mockito.mock(HandlerInterceptor.class); HandlerInterceptor i3 = Mockito.mock(HandlerInterceptor.class); MappedInterceptor mappedInterceptor3 = new MappedInterceptor(new String[]{"/**"}, i3); HandlerInterceptor i4 = Mockito.mock(HandlerInterceptor.class); this.handlerMapping.setInterceptors(mappedInterceptor1, i2, mappedInterceptor3, i4); this.handlerMapping.setApplicationContext(this.context); HandlerExecutionChain chain = this.handlerMapping.getHandlerExecutionChain(new SimpleHandler(), this.request); Assert.assertThat(chain.getInterceptors(), Matchers.arrayContaining( mappedInterceptor1.getInterceptor(), i2, mappedInterceptor3.getInterceptor(), i4)); }
@Before public void setup() { this.request = new MockHttpServletRequest(); this.response= new MockHttpServletResponse() ; this.handler = new Object(); this.chain = new HandlerExecutionChain(this.handler); this.interceptor1 = mock(AsyncHandlerInterceptor.class); this.interceptor2 = mock(AsyncHandlerInterceptor.class); this.interceptor3 = mock(AsyncHandlerInterceptor.class); this.chain.addInterceptor(this.interceptor1); this.chain.addInterceptor(this.interceptor2); assertEquals(2, this.chain.getInterceptors().length); this.chain.addInterceptor(this.interceptor3); assertEquals(3, this.chain.getInterceptors().length); }
@Test public void requestMappingHandlerMapping() throws Exception { ApplicationContext context = initContext(WebConfig.class, ScopedController.class, ScopedProxyController.class); RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class); assertEquals(0, handlerMapping.getOrder()); HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/")); assertNotNull(chain); assertNotNull(chain.getInterceptors()); assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[0].getClass()); chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/scoped")); assertNotNull("HandlerExecutionChain for '/scoped' mapping should not be null.", chain); chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/scopedProxy")); assertNotNull("HandlerExecutionChain for '/scopedProxy' mapping should not be null.", chain); }
@Test(expected = TypeMismatchException.class) public void testCustomConversionService() throws Exception { loadBeanDefinitions("mvc-config-custom-conversion-service.xml"); RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class); assertNotNull(mapping); mapping.setDefaultHandler(handlerMethod); // default web binding initializer behavior test MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); request.setRequestURI("/accounts/12345"); request.addParameter("date", "2009-10-31"); MockHttpServletResponse response = new MockHttpServletResponse(); HandlerExecutionChain chain = mapping.getHandler(request); assertEquals(1, chain.getInterceptors().length); assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor); ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[0]; interceptor.preHandle(request, response, handler); assertSame(appContext.getBean("conversionService"), request.getAttribute(ConversionService.class.getName())); RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class); assertNotNull(adapter); adapter.handle(request, response, handlerMethod); }
@Test public void getHandlerMappedInterceptors() throws Exception { String path = "/foo"; HandlerInterceptor interceptor = new HandlerInterceptorAdapter() {}; MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] {path}, interceptor); TestRequestMappingInfoHandlerMapping mapping = new TestRequestMappingInfoHandlerMapping(); mapping.registerHandler(new TestController()); mapping.setInterceptors(new Object[] { mappedInterceptor }); mapping.setApplicationContext(new StaticWebApplicationContext()); HandlerExecutionChain chain = mapping.getHandler(new MockHttpServletRequest("GET", path)); assertNotNull(chain); assertNotNull(chain.getInterceptors()); assertSame(interceptor, chain.getInterceptors()[0]); chain = mapping.getHandler(new MockHttpServletRequest("GET", "/invalid")); assertNull(chain); }