正文
(isGet ||
"HEAD"
.
equals
(method)) {
long
lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if
(
new
ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return
;
}
}
// 执行拦截器的preHandle方法
if
(!mappedHandler.applyPreHandle(processedRequest, response)) {
return
;
}
// Actually invoke the handler.
// 利用HandlerAdapter来执行Handler里对应的处理方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if
(asyncManager.isConcurrentHandlingStarted()) {
return
;
}
// 如果没有设置视图,则应用默认的视图名
applyDefaultViewName(processedRequest, mv);
// 执行拦截器的postHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch
(Exception ex) {
dispatchException = ex;
}
catch
(Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException =
new
NestedServletException(
"Handler dispatch failed"
, err);
}
// 根据ModelAndView对象解析视图
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch
(Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch
(Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new
NestedServletException(
"Handler processing failed"
, err));
}
finally
{
if
(asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if
(mappedHandler !=
null
) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else
{
// Clean up any resources used by a multipart request.
if
(multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
该方法就是
SpringMVC
处理请求的整体流程,其中涉及到几个重要的方法。
getHandler
/**
* Return the HandlerExecutionChain for this request.
* 为这个request返回一个HandlerExecutionChain
*/
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
根据调试信息可以看出,
getHandler
方法主要是从
List
handlerMappings
集合中遍历查找一个合适的处理器(
Handler
),返回的结果是一个
HandlerExecutionChain
。然后再根据
HandlerExecutionChain
里携带的
Handler
去获取
HandlerAdapter
。
getHandlerAdapter
/**
* Return the HandlerAdapter for this handler object.
* @param
handler the handler object to find an adapter for
* @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
*/
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
同样
getHandlerAdapter
方法主要是从
List
handlerAdapters
集合中遍历查找一个合适的处理器适配器(
HandlerAdapter
),返回的结果是一个
HandlerAdapter
。
可以看到此处
HandlerAdapter
真正的实现类是
RequestMappingHandlerAdapter
。
processDispatchResult
processDispatchResult
方法主要根据方法执行完成后封装的
ModelAndView
,转发到对应页面,定义如下
/**
* Handle the result of handler selection and handler invocation, which is
* either a ModelAndView or an Exception to be resolved to a ModelAndView.
*/
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
boolean errorView = false;
if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
}
else {
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}
// Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
// 主要调用该方法渲染视图
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No view rendering, null ModelAndView returned.");
}
}
if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Concurrent handling started during a forward
return;
}
if (mappedHandler != null) {
// Exception (if any) is already handled..
mappedHandler.triggerAfterCompletion(request, response, null);
}
}
render
/**
* Render the given ModelAndView.
* This is the last stage in handling a request. It may involve resolving the view by name.
* @param mv the ModelAndView to render
* @param request current HTTP servlet request
* @param response current HTTP servlet response
* @throws ServletException if view is missing or cannot be resolved
* @throws Exception if there's a problem rendering the view
*/
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
// Determine locale for request and apply it to the response.
Locale locale =
(this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale());
response.setLocale(locale);
View view;
String viewName = mv.getViewName();
if (viewName != null) {
// We need to resolve the view name.
// 根据给定的视图名称,解析获取View对象
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
"' in servlet with name '" + getServletName() + "'");
}
}
else {
// No need to lookup: the ModelAndView object contains the actual View object.
view = mv.getView();
if (view == null) {
throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
"View object in servlet with name '" + getServletName() + "'");
}
}
// Delegate to the View object for rendering.
if (logger.isTraceEnabled()) {
logger.trace("Rendering view [" + view + "] "