private void detectContentTypeFromPage(Content page, HttpServletResponse response) { String contentType = page.getProperty("meta.http-equiv.Content-Type"); if (contentType != null && "text/html".equals(response.getContentType())) { response.setContentType(contentType); } }
/* (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); } } }