Spring MVC 怎么处理请求
分两步:
- Servlet 处理过程
- DispatcherServlet 核心处理方法doDispatch
1.Servlet 处理过程
1.1 HttpServletBean
只参与了创建工作,没有涉及请求的处理。
1.2 FrameworkServlet
Servlet处理请求都是从Servlet接口的service方法开始,
然后HttpServlet的service方法中根据请求的类型不同,将请求路由到了:
- doGet
- doHead
- doPost
- doPut
- doDelete
- doOptions
- doTrace
七个方法,并且做了 doHead、doOptions和doTrace的默认实现,其中doHead调用doGet,然后返回只有header没有body的response。
- FrameworkServlet 重写了除doHead的所有处理请求的方法。
- 在service方法中增加了对PATCH类型请求的处理,其他类型的请求直接交给了父类进行处理;
- doOptions和doTrace方法可以通过设置
dispatchOpionsRequest
和dispatchTraceRequest
参数决定是自己处理还是交给父类处理(默认都是交给父类处理,doOptions会在父类的处理结果中增加PATCH类型); - doGet、doPost、doPut和doDelete都是自己处理。
- 所有需要自己处理的请求都交给了
processRequest
方法进行统一处理。
查看一下service方法和doGet方法的代码,其它需要自己处理的方法都与doGet方法类似。
// org.springframework.web.servlet.FrameworkServlet
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
// 统一处理请求
processRequest(request, response);
} else {
super.service(request, response);
}
}
@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 统一处理请求
processRequest(request, response);
}
在这里所做的事情跟HttpServlet里将来同类型的请求路由到不同方法进行处理的思路正好相反。这里将所有请求又合并到processRequest()
方