GrailsDispatcherServlet中的doDispatch方法

来源:互联网 发布:Python中eval() 编辑:程序博客网 时间:2024/06/05 13:43
@Overrideprotected 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();            if(previousRequestAttributes instanceof GrailsWebRequest) {                requestAttributes = new GrailsWebRequest(processedRequest, response, ((GrailsWebRequest)previousRequestAttributes).getAttributes());            } else {                requestAttributes = new GrailsWebRequest(processedRequest, response, getServletContext());            }            if( previousRequestAttributes != null) {                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);            Object handler = mappedHandler.getHandler();            if (mappedHandler == null || handler == null) {                noHandlerFound(processedRequest, response);                return;            }            HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();            // Apply preHandle methods of registered interceptors.            if (interceptors != null) {                int i = 0;                for (HandlerInterceptor interceptor : interceptors) {                    if (!interceptor.preHandle(processedRequest, response, handler)) {                        triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);                        return;                    }                    interceptorIndex = i;                    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(handler);                mv = ha.handle(processedRequest, response, handler);                // 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 (interceptors != null) {                for (int i = interceptors.length - 1; i >= 0; i--) {                    interceptors[i].postHandle(processedRequest, response, handler, 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 ? null : mappedHandler.getHandler();            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);        }    }}
0 0