/** * Test routes: GET /wildcard-a myTestController.wildcardA GET /wildcard-b * myTestController.wildcardB * * @throws Exception */ @Test public void wildcardRouteFiles() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/wildcard-a"); request.addHeader("host", sampleHost); HandlerExecutionChain chain = this.hm.getHandler(request); RouterHandler handler = (RouterHandler) chain.getHandler(); Assert.assertNotNull(handler); Route route = handler.getRoute(); Assert.assertNotNull(route); Assert.assertEquals(this.handlerName + ".wildcardA", route.action); request = new MockHttpServletRequest("GET", "/wildcard-b"); request.addHeader("host", sampleHost); chain = this.hm.getHandler(request); handler = (RouterHandler) chain.getHandler(); Assert.assertNotNull(handler); route = handler.getRoute(); Assert.assertNotNull(route); Assert.assertEquals(this.handlerName + ".wildcardB", route.action); }
public void testMapSimpleUri() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/welcome"); HandlerExecutionChain chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("welcome"), chain.getHandler()); request = new MockHttpServletRequest("GET", "/welcome/product"); chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("welcome"), chain.getHandler()); }
public void testWithMultiActionControllerMapping() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/admin/user"); HandlerExecutionChain chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("admin"), chain.getHandler()); request = new MockHttpServletRequest("GET", "/admin/product"); chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("admin"), chain.getHandler()); }
public void testIndexUri() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index"); HandlerExecutionChain chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("index"), chain.getHandler()); request = new MockHttpServletRequest("GET", "/index/product"); chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("index"), chain.getHandler()); }
public void testWithoutControllerSuffix() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/buyform"); HandlerExecutionChain chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("buy"), chain.getHandler()); request = new MockHttpServletRequest("GET", "/buyform/product"); chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("buy"), chain.getHandler()); }
@Override protected HandlerExecutionChain getHandlerExecutionChain( Object handler, HttpServletRequest request) { HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request); HandlerInterceptor[] interceptors = addSecurityInterceptor(chain.getInterceptors()); return new HandlerExecutionChain(chain.getHandler(), interceptors); }
public void testWithRootAsBasePackage() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/myapp/org/springframework/web/servlet/mvc/mapping/welcome"); HandlerExecutionChain chain = this.hm4.getHandler(request); assertEquals(this.wac.getBean("welcome"), chain.getHandler()); }
@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; }
public ModelAndView excuteAction(HttpServletRequest request, HttpServletResponse response) throws Exception { // 这里需要声明request的实际类型,否则会报错 request.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING, true); HandlerExecutionChain chain = handlerMapping.getHandler(request); ModelAndView model = null; try { model = handlerAdapter.handle(request, response, chain.getHandler()); } catch (Exception e) { e.printStackTrace(); } return model; }
/** * Test route: GET /simpleaction myTestController.simpleAction * * @throws Exception */ @Test public void testSimpleRoute() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/simpleaction"); request.addHeader("host", sampleHost); HandlerExecutionChain chain = this.hm.getHandler(request); RouterHandler handler = (RouterHandler) chain.getHandler(); Assert.assertNotNull(handler); Route route = handler.getRoute(); Assert.assertNotNull(route); Assert.assertEquals(this.handlerName + ".simpleAction", route.action); }
/** * Test route: GET /caseinsensitive MyTestCONTROLLER.caseInsensitive * * @throws Exception */ @Test public void caseInsensitiveRoute() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/caseinsensitive"); request.addHeader("host", sampleHost); HandlerExecutionChain chain = this.hm.getHandler(request); RouterHandler handler = (RouterHandler) chain.getHandler(); Assert.assertNotNull(handler); Route route = handler.getRoute(); Assert.assertNotNull(route); Assert.assertTrue((this.handlerName + ".caseInsensitive").equalsIgnoreCase(route.action)); }
/** * Test route: PUT /http myTestController.httpAction(type:'PUT') with a GET request and a * "x-http-method-override" argument in queryString * * @throws Exception */ @Test public void testOverrideQueryStringHTTPAction() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/http"); request.setQueryString("x-http-method-override=PUT"); request.addHeader("host", sampleHost); HandlerExecutionChain chain = this.hm.getHandler(request); RouterHandler handler = (RouterHandler) chain.getHandler(); Assert.assertNotNull(handler); Route route = handler.getRoute(); Assert.assertNotNull(route); Assert.assertEquals(this.handlerName + ".httpAction", route.action); }
/** * Passes the given request to a proper controller. * * @param request * @return * @throws Exception */ public MockHttpServletResponse handle(HttpServletRequest request) throws Exception { MockHttpServletResponse response = new MockHttpServletResponse(); HandlerExecutionChain handlerExecutionChain = null; for (DefaultAnnotationHandlerMapping handlerMapping : handlerMappings) { handlerExecutionChain = handlerMapping.getHandler(request); if (handlerExecutionChain != null) { break; } } Assert.assertNotNull("The request URI does not exist", handlerExecutionChain); handlerAdapter.handle(request, response, handlerExecutionChain.getHandler()); return response; }
/** * This method finds the handler for a given request URI, or throws an exception if none were * found. * * <p>It will also ensure that the URI Parameters i.e. /context/test/{name} are added to the * request * * @param request the request for which to find a handler * @return The handler that agreed to handle the specified request. * @throws NoSuchMethodException if no acceptable handlers could be found */ protected Object getHandler(final MockHttpServletRequest request) throws NoSuchMethodException { HandlerExecutionChain chain = null; // NOPMD by jon.adams on 5/14/12 final Map<String, HandlerMapping> map = applicationContext.getBeansOfType(HandlerMapping.class); final Iterator<HandlerMapping> itt = map.values().iterator(); while (itt.hasNext()) { final HandlerMapping mapping = itt.next(); try { chain = mapping.getHandler(request); } catch (final HttpRequestMethodNotSupportedException exc) { // ignore and try next LOGGER.info( mapping.getClass().getName() + " handler determined it will not handle the request. Message: " + exc.getMessage(), exc); } catch (final Exception exc) { throw new RuntimeException(exc); // NOPMD } if (chain == null) { // ignore and try next LOGGER.debug( mapping.getClass().getName() + " handler determined it will not handle the request."); } else { // found one. quit looking for more. break; } } if (chain == null) { throw new NoSuchMethodException( "Unable to find handler for request URI: " + request.getRequestURI()); } return chain.getHandler(); }
/** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors. Will just invoke * afterCompletion for all interceptors whose preHandle invocation has successfully completed and * returned true. * * @param mappedHandler the mapped HandlerExecutionChain * @param interceptorIndex index of last interceptor that successfully completed * @param ex Exception thrown on handler execution, or <code>null</code> if none * @see HandlerInterceptor#afterCompletion */ protected void triggerAfterCompletion( HandlerExecutionChain mappedHandler, int interceptorIndex, HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { if (mappedHandler == null || mappedHandler.getInterceptors() == null) { return; } // Apply afterCompletion methods of registered interceptors. for (int i = interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; try { interceptor.afterCompletion(request, response, mappedHandler.getHandler(), ex); } catch (Throwable e) { stackFilterer.filter(e, true); logger.error("HandlerInterceptor.afterCompletion threw exception", e); } } }
/** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors. Will just invoke * afterCompletion for all interceptors whose preHandle invocation has successfully completed and * returned true. * * @param mappedHandler the mapped HandlerExecutionChain * @param interceptorIndex index of last interceptor that successfully completed * @param ex Exception thrown on handler execution, or <code>null</code> if none * @see HandlerInterceptor#afterCompletion */ protected void triggerAfterCompletion( HandlerExecutionChain mappedHandler, int interceptorIndex, HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { // Apply afterCompletion methods of registered interceptors. if (mappedHandler != null) { if (mappedHandler.getInterceptors() != null) { for (int i = interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; try { interceptor.afterCompletion(request, response, mappedHandler.getHandler(), ex); } catch (Throwable ex2) { GrailsUtil.deepSanitize(ex2); logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } } }
public void testWithBasePackageAndCaseSensitive() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/mvc/mapping/buyForm"); HandlerExecutionChain chain = this.hm2.getHandler(request); assertEquals(this.wac.getBean("buy"), chain.getHandler()); }
public void testWithContextPath() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/welcome"); request.setContextPath("/myapp"); HandlerExecutionChain chain = this.hm.getHandler(request); assertEquals(this.wac.getBean("welcome"), chain.getHandler()); }
/* (non-Javadoc) * @see org.springframework.web.servlet.DispatcherServlet#doDispatch(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception { request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, localeResolver); HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; int interceptorIndex = -1; // Expose current LocaleResolver and request as LocaleContext. LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext(); LocaleContextHolder.setLocaleContext( new LocaleContext() { public Locale getLocale() { return localeResolver.resolveLocale(request); } }); // If the request is an include we need to try to use the original wrapped sitemesh // response, otherwise layouts won't work properly if (WebUtils.isIncludeRequest(request)) { response = useWrappedOrOriginalResponse(response); } GrailsWebRequest requestAttributes = null; RequestAttributes previousRequestAttributes = null; Exception handlerException = null; boolean isAsyncRequest = processedRequest.getAttribute("javax.servlet.async.request_uri") != null; try { ModelAndView mv; boolean errorView = false; try { Object exceptionAttribute = request.getAttribute(EXCEPTION_ATTRIBUTE); // only process multipart requests if an exception hasn't occured if (exceptionAttribute == null) { processedRequest = checkMultipart(request); } // Expose current RequestAttributes to current thread. previousRequestAttributes = RequestContextHolder.currentRequestAttributes(); requestAttributes = new GrailsWebRequest(processedRequest, response, getServletContext()); copyParamsFromPreviousRequest(previousRequestAttributes, requestAttributes); // Update the current web request. WebUtils.storeGrailsWebRequest(requestAttributes); if (logger.isDebugEnabled()) { logger.debug("Bound request context to thread: " + request); logger.debug("Using response object: " + response.getClass()); } // Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Apply preHandle methods of registered interceptors. if (mappedHandler.getInterceptors() != null) { for (int i = 0; i < mappedHandler.getInterceptors().length; i++) { HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { triggerAfterCompletion( mappedHandler, interceptorIndex, processedRequest, response, null); return; } interceptorIndex = i; } } // if this is an async request that has been resumed, then don't execute the action again // instead try get the model and view and continue if (isAsyncRequest) { Object modelAndViewO = processedRequest.getAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW); if (modelAndViewO != null) { mv = (ModelAndView) modelAndViewO; } else { mv = null; } } else { // Actually invoke the handler. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // if an async request was started simply return if (processedRequest.getAttribute(GrailsApplicationAttributes.ASYNC_STARTED) != null) { processedRequest.setAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, mv); return; } // Do we need view name translation? if ((ha instanceof AnnotationMethodHandlerAdapter || ha instanceof RequestMappingHandlerAdapter) && mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } } // Apply postHandle methods of registered interceptors. if (mappedHandler.getInterceptors() != null) { for (int i = mappedHandler.getInterceptors().length - 1; i >= 0; i--) { HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv); } } } catch (ModelAndViewDefiningException ex) { handlerException = ex; if (logger.isDebugEnabled()) { logger.debug("ModelAndViewDefiningException encountered", ex); } mv = ex.getModelAndView(); } catch (Exception ex) { handlerException = ex; Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(request, response, handler, ex); errorView = (mv != null); } // Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { // If an exception occurs in here, like a bad closing tag, // we have nothing to render. try { render(mv, processedRequest, response); if (isAsyncRequest && (response instanceof GrailsContentBufferingResponse)) { GroovyPageLayoutFinder groovyPageLayoutFinder = getWebApplicationContext() .getBean("groovyPageLayoutFinder", GroovyPageLayoutFinder.class); GrailsContentBufferingResponse bufferingResponse = (GrailsContentBufferingResponse) response; HttpServletResponse targetResponse = bufferingResponse.getTargetResponse(); Content content = bufferingResponse.getContent(); if (content != null) { Decorator decorator = groovyPageLayoutFinder.findLayout(request, content); SiteMeshWebAppContext webAppContext = new SiteMeshWebAppContext(request, targetResponse, getServletContext()); if (decorator != null) { if (decorator instanceof com.opensymphony.sitemesh.Decorator) { ((com.opensymphony.sitemesh.Decorator) decorator).render(content, webAppContext); } else { new OldDecorator2NewDecorator(decorator).render(content, webAppContext); } } else { content.writeOriginal(targetResponse.getWriter()); } } } if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } catch (Exception e) { // Only render the error view if we're not already trying to render it. // This prevents a recursion if the error page itself has errors. if (request.getAttribute(GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE) == null) { request.setAttribute( GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE, Boolean.TRUE); mv = super.processHandlerException(processedRequest, response, mappedHandler, e); handlerException = e; if (mv != null) render(mv, processedRequest, response); } else { request.removeAttribute(GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE); logger.warn("Recursive rendering of error view detected.", e); try { response.setContentType("text/plain"); response.getWriter().write("Internal server error"); response.flushBuffer(); } catch (Exception e2) { logger.error("Internal server error - problem rendering error view", e2); } requestAttributes.setRenderView(false); return; } } } 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, handlerException); } 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 instanceof MultipartHttpServletRequest) { if (multipartResolver != null) { multipartResolver.cleanupMultipart((MultipartHttpServletRequest) processedRequest); } } request.removeAttribute(MultipartHttpServletRequest.class.getName()); // Reset thread-bound holders if (requestAttributes != null) { requestAttributes.requestCompleted(); if (previousRequestAttributes instanceof GrailsWebRequest) { WebUtils.storeGrailsWebRequest((GrailsWebRequest) previousRequestAttributes); } else { RequestContextHolder.setRequestAttributes(previousRequestAttributes); } } LocaleContextHolder.setLocaleContext(previousLocaleContext); if (logger.isDebugEnabled()) { logger.debug("Cleared thread-bound request context: " + request); } } }
public void testWithFullBasePackage() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/welcome"); HandlerExecutionChain chain = this.hm3.getHandler(request); assertEquals(this.wac.getBean("welcome"), chain.getHandler()); }
@Test public void webMvcConfigurerExtensionHooks() throws Exception { StaticWebApplicationContext appCxt = new StaticWebApplicationContext(); appCxt.setServletContext(new MockServletContext(new FileSystemResourceLoader())); appCxt.registerSingleton("controller", TestController.class); WebConfig webConfig = new WebConfig(); webConfig.setApplicationContext(appCxt); webConfig.setServletContext(appCxt.getServletContext()); String actual = webConfig.mvcConversionService().convert(new TestBean(), String.class); assertEquals("converted", actual); RequestMappingHandlerAdapter adapter = webConfig.requestMappingHandlerAdapter(); assertEquals(1, adapter.getMessageConverters().size()); ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer(); assertNotNull(initializer); BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(null, ""); initializer.getValidator().validate(null, bindingResult); assertEquals("invalid", bindingResult.getAllErrors().get(0).getCode()); @SuppressWarnings("unchecked") List<HandlerMethodArgumentResolver> argResolvers = (List<HandlerMethodArgumentResolver>) new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers"); assertEquals(1, argResolvers.size()); @SuppressWarnings("unchecked") List<HandlerMethodReturnValueHandler> handlers = (List<HandlerMethodReturnValueHandler>) new DirectFieldAccessor(adapter).getPropertyValue("customReturnValueHandlers"); assertEquals(1, handlers.size()); HandlerExceptionResolverComposite composite = (HandlerExceptionResolverComposite) webConfig.handlerExceptionResolver(); assertEquals(1, composite.getExceptionResolvers().size()); RequestMappingHandlerMapping rmHandlerMapping = webConfig.requestMappingHandlerMapping(); rmHandlerMapping.setApplicationContext(appCxt); HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/")); assertNotNull(chain.getInterceptors()); assertEquals(2, chain.getInterceptors().length); assertEquals(LocaleChangeInterceptor.class, chain.getInterceptors()[0].getClass()); assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[1].getClass()); AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) webConfig.viewControllerHandlerMapping(); handlerMapping.setApplicationContext(appCxt); assertNotNull(handlerMapping); assertEquals(1, handlerMapping.getOrder()); HandlerExecutionChain handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/path")); assertNotNull(handler.getHandler()); handlerMapping = (AbstractHandlerMapping) webConfig.resourceHandlerMapping(); handlerMapping.setApplicationContext(appCxt); assertNotNull(handlerMapping); assertEquals(Integer.MAX_VALUE - 1, handlerMapping.getOrder()); handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/resources/foo.gif")); assertNotNull(handler.getHandler()); handlerMapping = (AbstractHandlerMapping) webConfig.defaultServletHandlerMapping(); handlerMapping.setApplicationContext(appCxt); assertNotNull(handlerMapping); assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/anyPath")); assertNotNull(handler.getHandler()); }
/* (non-Javadoc) * @see org.springframework.web.servlet.DispatcherServlet#doDispatch(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; int interceptorIndex = -1; final LocaleResolver localeResolver = (LocaleResolver) request.getAttribute(LOCALE_RESOLVER_ATTRIBUTE); // Expose current LocaleResolver and request as LocaleContext. LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext(); LocaleContextHolder.setLocaleContext( new LocaleContext() { public Locale getLocale() { return localeResolver.resolveLocale(request); } }); // If the request is an include we need to try to use the original wrapped sitemesh // response, otherwise layouts won't work properly if (WebUtils.isIncludeRequest(request)) { response = useWrappedOrOriginalResponse(response); } GrailsWebRequest requestAttributes = null; GrailsWebRequest previousRequestAttributes = null; Exception handlerException = null; try { ModelAndView mv = null; try { Object exceptionAttribute = request.getAttribute(EXCEPTION_ATTRIBUTE); // only process multipart requests if an exception hasn't occured if (exceptionAttribute == null) processedRequest = checkMultipart(request); // Expose current RequestAttributes to current thread. previousRequestAttributes = (GrailsWebRequest) RequestContextHolder.currentRequestAttributes(); requestAttributes = new GrailsWebRequest(processedRequest, response, getServletContext()); copyParamsFromPreviousRequest(previousRequestAttributes, requestAttributes); // Update the current web request. WebUtils.storeGrailsWebRequest(requestAttributes); if (logger.isDebugEnabled()) { logger.debug("Bound request context to thread: " + request); logger.debug("Using response object: " + response.getClass()); } // Determine handler for the current request. mappedHandler = getHandler(processedRequest, false); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Apply preHandle methods of registered interceptors. if (mappedHandler.getInterceptors() != null) { for (int i = 0; i < mappedHandler.getInterceptors().length; i++) { HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { triggerAfterCompletion( mappedHandler, interceptorIndex, processedRequest, response, null); return; } interceptorIndex = i; } } // Actually invoke the handler. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Apply postHandle methods of registered interceptors. if (mappedHandler.getInterceptors() != null) { for (int i = mappedHandler.getInterceptors().length - 1; i >= 0; i--) { HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv); } } } catch (ModelAndViewDefiningException ex) { GrailsUtil.deepSanitize(ex); handlerException = ex; if (logger.isDebugEnabled()) logger.debug("ModelAndViewDefiningException encountered", ex); mv = ex.getModelAndView(); } catch (Exception ex) { GrailsUtil.deepSanitize(ex); handlerException = ex; Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(request, response, handler, ex); } // Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { // If an exception occurs in here, like a bad closing tag, // we have nothing to render. try { render(mv, processedRequest, response); } catch (Exception e) { mv = super.processHandlerException(processedRequest, response, mappedHandler, e); handlerException = e; render(mv, processedRequest, response); } } 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, handlerException); } 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 instanceof MultipartHttpServletRequest && processedRequest != request) { if (multipartResolver != null) this.multipartResolver.cleanupMultipart((MultipartHttpServletRequest) processedRequest); } request.removeAttribute(MultipartHttpServletRequest.class.getName()); // Reset thread-bound holders if (requestAttributes != null) { requestAttributes.requestCompleted(); WebUtils.storeGrailsWebRequest(previousRequestAttributes); } LocaleContextHolder.setLocaleContext(previousLocaleContext); if (logger.isDebugEnabled()) { logger.debug("Cleared thread-bound request context: " + request); } } }