@Override public void init(FilterConfig fc) { super.init(fc); this.filterConfig = fc; containerTweaks = new ContainerTweaks(); Config config = new Config(fc); // DefaultFactory defaultFactory = new DefaultFactory(config); Grails5535Factory defaultFactory = new Grails5535Factory(config); // TODO revert once Sitemesh bug is fixed fc.getServletContext().setAttribute(FACTORY_SERVLET_CONTEXT_ATTRIBUTE, defaultFactory); defaultFactory.refresh(); FactoryHolder.setFactory(defaultFactory); contentProcessor = new PageParser2ContentProcessor(defaultFactory); decoratorMapper = defaultFactory.getDecoratorMapper(); applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(fc.getServletContext()); layoutViewResolver = WebUtils.lookupViewResolver(applicationContext); final GrailsApplication grailsApplication = GrailsWebUtil.lookupApplication(fc.getServletContext()); String encoding = (String) grailsApplication.getFlatConfig().get(CONFIG_OPTION_GSP_ENCODING); if (encoding != null) { defaultEncoding = encoding; } Map<String, PersistenceContextInterceptor> interceptors = applicationContext.getBeansOfType(PersistenceContextInterceptor.class); if (!interceptors.isEmpty()) { persistenceInterceptor = interceptors.values().iterator().next(); } }
@Override protected View createFallbackView(String viewName) throws Exception { GrailsWebRequest webRequest = GrailsWebRequest.lookup(); String[] viewNameParts = splitViewName(viewName); if (viewNameParts.length == 1) { viewName = WebUtils.addViewPrefix(viewName, webRequest.getControllerName()); viewNameParts = splitViewName(viewName); } View v = scaffoldedViews.get(viewName); if (v == null) { GrailsDomainClass domainClass = scaffoldedDomains.get(viewNameParts[0]); if (domainClass != null) { String viewCode = null; try { viewCode = generateViewSource(viewNameParts[1], domainClass); } catch (Exception e) { log.error("Error generating scaffolded view [" + viewName + "]: " + e.getMessage(), e); } if (StringUtils.hasLength(viewCode)) { v = createScaffoldedView(viewName, viewCode); scaffoldedViews.put(viewName, v); } } } if (v != null) { return v; } return super.createFallbackView(viewName); }
private View createGrailsView(String viewName) throws Exception { // try GSP if res is null GrailsWebRequest webRequest = WebUtils.retrieveGrailsWebRequest(); HttpServletRequest request = webRequest.getCurrentRequest(); GroovyObject controller = webRequest.getAttributes().getController(request); if (grailsApplication == null) { grailsApplication = getApplicationContext() .getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class); } ResourceLoader loader = establishResourceLoader(grailsApplication); String format = request.getAttribute(GrailsApplicationAttributes.CONTENT_FORMAT) != null ? request.getAttribute(GrailsApplicationAttributes.CONTENT_FORMAT).toString() : null; String gspView = localPrefix + viewName + DOT + format + GSP_SUFFIX; Resource res = null; if (format != null) { res = loader.getResource(gspView); if (!res.exists()) { View v = lookupBinaryPluginView(webRequest, controller, gspView); if (v != null) { return v; } gspView = resolveViewForController(controller, grailsApplication, viewName, loader); res = loader.getResource(gspView); } } if (res == null || !res.exists()) { gspView = localPrefix + viewName + GSP_SUFFIX; res = loader.getResource(gspView); if (!res.exists()) { View v = lookupBinaryPluginView(webRequest, controller, gspView); if (v != null) { return v; } gspView = resolveViewForController(controller, grailsApplication, viewName, loader); res = loader.getResource(gspView); } } if (res.exists()) { return createGroovyPageView(webRequest, gspView); } AbstractUrlBasedView view = buildView(viewName); view.setApplicationContext(getApplicationContext()); view.afterPropertiesSet(); return view; }
/** * Converts this parameter map into a query String. Note that this will flatten nested keys * separating them with the . character and URL encode the result * * @return A query String starting with the ? character */ public String toQueryString() { String encoding = request.getCharacterEncoding(); try { return WebUtils.toQueryString(this, encoding); } catch (UnsupportedEncodingException e) { throw new ControllerExecutionException( "Unable to convert parameter map [" + this + "] to a query string: " + e.getMessage(), e); } }
protected void logRequestDetails( HttpServletRequest request, ContentCacheParameters cacheParameters, String message) { if (!log.isDebugEnabled()) { return; } log.debug("{}...", message); log.debug(" method = {}", request.getMethod()); log.debug(" requestURI = {}", request.getRequestURI()); log.debug(" forwardURI = {}", WebUtils.getForwardURI(request)); if (WebUtils.isIncludeRequest(request)) { log.debug( " includeURI = {}", request.getAttribute(WebUtils.INCLUDE_REQUEST_URI_ATTRIBUTE)); } log.debug(" controller = {}", cacheParameters.getControllerName()); log.debug(" action = {}", cacheParameters.getActionName()); RequestMimeTypesApi requestMimeTypesApi = getBean("requestMimeTypesApi"); log.debug(" format = {}", requestMimeTypesApi.getFormat(request)); log.debug(" params = {}", cacheParameters.getParams()); }
protected PageInfo buildPage( HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // Invoke the next entity in the chain SerializableByteArrayOutputStream out = new SerializableByteArrayOutputStream(); GenericResponseWrapper wrapper = new GenericResponseWrapper(response, out); Map<String, Serializable> cacheableRequestAttributes = new HashMap<String, Serializable>(); // TODO: split the special include handling out into a separate method HttpServletResponse originalResponse = null; boolean isInclude = WebUtils.isIncludeRequest(request); if (isInclude) { originalResponse = WrappedResponseHolder.getWrappedResponse(); WrappedResponseHolder.setWrappedResponse(wrapper); } try { List<String> attributesBefore = toList(request.getAttributeNames()); chain.doFilter(request, wrapper); List<String> attributesAfter = toList(request.getAttributeNames()); attributesAfter.removeAll(attributesBefore); for (String attrName : attributesAfter) { Object value = request.getAttribute(attrName); if (value instanceof Serializable) { cacheableRequestAttributes.put(attrName, (Serializable) value); } } } finally { if (isInclude) { WrappedResponseHolder.setWrappedResponse(originalResponse); } } wrapper.flush(); long timeToLiveSeconds = Integer .MAX_VALUE; // TODO // cacheManager.getEhcache(context.cacheName).cacheConfiguration.timeToLiveSeconds; String contentType = wrapper.getContentType(); if (!StringUtils.hasLength(contentType)) { contentType = response.getContentType(); } return new PageInfo( wrapper.getStatus(), contentType, out.toByteArray(), false, timeToLiveSeconds, wrapper.getAllHeaders(), wrapper.getCookies(), cacheableRequestAttributes); }
/** * Writes the response from a PageInfo object. * * <p>Headers are set last so that there is an opportunity to override * * <p>1 - only set status, contentType, cookies, etc. if this is the "main" request and not an * include. 2 - send a status code 304 if appropriate. * * @param request * @param response * @param pageInfo * @throws IOException */ protected void writeResponse( final HttpServletRequest request, final HttpServletResponse response, final PageInfo pageInfo) throws IOException { if (!WebUtils.isIncludeRequest(request)) { int statusCode = determineResponseStatus(request, pageInfo); response.setStatus(statusCode); setContentType(response, pageInfo); setCookies(pageInfo, response); setHeaders(pageInfo, response); } writeResponse(response, pageInfo); }
@Override protected View loadView(String viewName, Locale locale) throws Exception { final View resolvedView = super.loadView(viewName, locale); if (templateGenerator == null || resolvedView instanceof GroovyPageView) { return resolvedView; } GrailsWebRequest webRequest = WebUtils.retrieveGrailsWebRequest(); List<String> controllerActions = scaffoldedActionMap.get(webRequest.getControllerName()); if (controllerActions != null && controllerActions.contains(webRequest.getActionName())) { GrailsDomainClass domainClass = scaffoldedDomains.get(webRequest.getControllerName()); if (domainClass != null) { String viewFileName; final int i = viewName.lastIndexOf('/'); if (i > -1) { viewFileName = viewName.substring(i, viewName.length()); } else { viewFileName = viewName; } final ViewKey viewKey = new ViewKey(webRequest.getControllerName(), viewFileName); View v = scaffoldedViews.get(viewKey); if (v == null) { String viewCode = null; try { viewCode = generateViewSource(webRequest, domainClass); } catch (Exception e) { GrailsUtil.deepSanitize(e); LOG.error("Error generating scaffolded view [" + viewName + "]: " + e.getMessage(), e); return resolvedView; } v = createScaffoldedView(viewName, viewCode); scaffoldedViews.put(viewKey, v); } if (v != null) { return v; } } } return resolvedView; }
protected String getCachedUri(HttpServletRequest request) { if (WebUtils.isIncludeRequest(request)) { return (String) request.getAttribute(WebUtils.INCLUDE_REQUEST_URI_ATTRIBUTE); } return request.getRequestURI(); }
/* (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); } } }
@Override protected void initStrategies(ApplicationContext context) { super.initStrategies(context); initLocaleResolver(context); layoutViewResolver = WebUtils.lookupViewResolver(context); }