1.Servlet
1.1Servlet概述
servlet 是在 Web 服务器中运行的小型 Java 程序。Servlet 接收和响应来自 Web 客户端的请求,通常是通过 HTTP(超文本传输协议)。它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。该接口主要用于接收请求参数,设置响应参数,在前后端中处理业务逻辑层的事务。
1.2Servlet体系结构
GenericServlet
:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
HttpServlet
:对http协议的一种封装,简化操作
1.3HttpServlet概述
HttpServlet 是一个抽象类,它属于 javax.servlet.http.HttpServlet
包。要创建一个 servlet,类必须继承 HttpServlet 类并重写至少一个方法(doGet、doPost、doDelete、doPut)。如果 servlet 支持 HTTP GET 请求,则为 doGet;对于 HTTP POST 请求,则为 doPost;对于 HTTP PUT 请求,则为 doPut。
2.SpringMVC&SpringBoot请求映射原理
当我们每次发送请求时,系统是如何找到对应的方法来处理请求的呢?为了解决这个问题,我们查看SpringMVC的底层源代码
2.1DispatcherServlet
- SpringBoot底层还是使用的SpringMVC,当客户端浏览器发送请求时,都会到达
DispatcherServlet
,而DispatcherServlet
继承于FrameworkServlet
,FrameworkServlet
继承于HttpServletBean
,HttpServletBean
继承于HttpServlet
,所以本质上DispatcherServlet
是一个Servlet。
- 那么,在这些类中就要实现
doGet()
或者doPost()
方法。我们看到,在HttpServletBean
这个类中并没有实现doGet后者doPost方法,那么我们查看FrameworkServlet
类代码。
- 可以看到四个方法都覆盖了
HttpServlet
中对应的方法,且实现都是processRequest()
方法。
- 实际的事件处理由抽象
doService
模板方法执行。
- 子类必须实现此方法来完成请求处理的工作,接收 GET、POST、PUT 和 DELETE 的集中回调。
- 发现其本身是抽象方法,查看其子类
DispatcherServlet
当中的定义情况。
公开DispatcherServlet特定的请求属性,并委托给doDispatch
进行实际调度。即该方法内的核心是调用了doDispatch()
方法来处理请求和响应。
2.2doDispatch()方法
源码如下:
客户端发送Http请求,debug测试:
可以看到请求的路径就是为/reflect
断点到达mappedHandler.getHandler()
所在行,这个方法决定哪个handler(controller中的方法)处理当前请求。然后放行,查看handler是什么。
选中mappedHandler = this.getHandler(processedRequest)
的执行结果:可以查看已经映射到对应的方法
2.3HandlerMapping
进入getHandler()
方法
在方法的首行,获取了handlerMappings
处理器映射,SpringMVC根据处理器映射里面的映射规则找到对应的处理方法。默认有5个HandlerMapping。
- 其中第一个
RequestMappingHandlerMapping
中保存了@RequestMapping和handler
的映射规则。当我们的应用一启动,SpringMVC自动扫描所有的Controller
并解析注解,把注解信息保存在handlerMapping
映射处理器中。
- 可以将这个HandlerMapping理解为一个Map,其中key为请求路径,value为handler的处理方法。
- 然后通过循环遍历着5个handlerMapping,看哪个可以处理当前请求。所以在
getHandler()
方法中,存在一个for循环,为了找到能处理对应请求的HandlerMapping。
进入循环中,当获取到RequestMappingHandlerMapping
时,我们查看这个类中的属性值,可以看到所有标注了@RequestMapping
注解的请求映射规则都已经存放在了这个RequestMappingHandlerMapping
类中
同时,已经获取到了相应的handler,也就是对应的Controller处理方法
2.4总结
所有的请求映射都保存在HandlerMapping
(映射处理器)中,在项目启动时,SpringMVC会自动扫描Controller并解析注解,将注解信息和处理方法保存在HandlerMapping映射处理器中。
SpringBoot为我们默认定义并配置了5个HandlerMapping,当一个请求进来时,系统会遍历这5个HandlerMapping,根据请求路径找到匹配的handler处理方法。
我们也可以将自定义的HandlerMapping放入容器中,使用自定义的映射处理器。