调用顺序:
-
Filter.doFilter() (自定义Filter)
//do something (处理请求)
-
chain.doFilter()
//...
-
DispatcherServlet (所有请求都经过这个Servlet分发)
- Interceptor.preHandle()
- Controller
- Interceptor.postHandle
- @ExceptionHandler
- Interceptor.afterCompletion()
//...
do something (处理响应)
DispatcherServlet.doDispatch()
/**
* 用于HTTP请求处理程序/控制器的中央分派器,例如用于web UI控制器或基于HTTP的远程服务导出器。
* 分派给注册的处理程序以处理web请求,提供方便的映射和异常处理功能。
*/
public class DispatcherServlet extends FrameworkServlet {
/**
* 所有HTTP方法都由该方法处理。由HandlerAdapters或处理程序自己决定哪些方法是可接受的。
* 参数:request–当前HTTP请求
* response–当前HTTP响应
*/
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//根据content-type判断,是multipart类型且未解析,就解析并返回MultipartHttpServletRequest,否则返回原request
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 确定当前请求的处理程序
mappedHandler = getHandler(processedRequest); // 图-mappedHandler
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 确定当前请求的处理程序适配器。
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 如果处理程序支持,则处理上次修改的报头。
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//调拦截器 Interceptor.preHandle
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 实际上调用处理程序。
//调Controller
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
//调拦截器 Interceptor.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 ServletException("Handler dispatch failed: " + err, err);
}
//调@ExceptionHandler
//调拦截器 Interceptor.afterCompletion
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new ServletException("Handler processing failed: " + err, 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);
}
}
}
}
}