/** * Process this request, publishing an event regardless of the outcome. * * <p>The actual event handling is performed by the abstract {@link #doService} template method. */ protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { long startTime = System.currentTimeMillis(); Throwable failureCause = null; LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext(); LocaleContext localeContext = buildLocaleContext(request); RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes); WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); asyncManager.registerCallableInterceptor( FrameworkServlet.class.getName(), new RequestBindingInterceptor()); initContextHolders(request, localeContext, requestAttributes); try { doService(request, response); } catch (ServletException ex) { failureCause = ex; throw ex; } catch (IOException ex) { failureCause = ex; throw ex; } catch (Throwable ex) { failureCause = ex; throw new NestedServletException("Request processing failed", ex); } finally { resetContextHolders(request, previousLocaleContext, previousAttributes); if (requestAttributes != null) { requestAttributes.requestCompleted(); } if (logger.isDebugEnabled()) { if (failureCause != null) { this.logger.debug("Could not complete request", failureCause); } else { if (asyncManager.isConcurrentHandlingStarted()) { logger.debug("Leaving response open for concurrent processing"); } else { this.logger.debug("Successfully completed request"); } } } publishRequestHandledEvent(request, response, startTime, failureCause); } }
/** * Create a HttpPost for the given configuration. * * <p>The default implementation creates a standard HttpPost with * "application/x-java-serialized-object" as "Content-Type" header. * * @param config the HTTP invoker configuration that specifies the target service * @return the HttpPost instance * @throws java.io.IOException if thrown by I/O methods */ protected HttpPost createHttpPost(HttpInvokerClientConfiguration config) throws IOException { HttpPost httpPost = new HttpPost(config.getServiceUrl()); LocaleContext localeContext = LocaleContextHolder.getLocaleContext(); if (localeContext != null) { Locale locale = localeContext.getLocale(); if (locale != null) { httpPost.addHeader(HTTP_HEADER_ACCEPT_LANGUAGE, StringUtils.toLanguageTag(locale)); } } if (isAcceptGzipEncoding()) { httpPost.addHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); } return httpPost; }
/* (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); } } }
/* (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); } } }