您的位置:首页 > 大数据 > 人工智能

GrailsDispatcherServlet中的doDispatch方法

2015-08-21 11:23 405 查看
@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();
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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: