之前看过一些这方面的资料,有几个博主写的很不错,但是侧重点不太一样。
我从自己的理解把内容总结一下,主要是方便自己记忆和理解。
先假设请求的连接是:http://localhost:8080/wcc/index.jsp
请求从web到容器tomcat
如果是域名访问,那么会有一个寻找对应IP的过程:
客户端先检查本地是否有对应的IP地址,若找到则返回响应的IP地址。若没找到则请求上级DNS服务器,直至找到或到根节点。
(浏览器缓存→系统缓存→路由器缓存→ISP DNS缓存→从根域名服务器递归搜索)
然后,通过三次握手,建立连接。
tomcat拿到请求到系统
1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
<!-- port:所在监听端口,protocol:协议版本号,connectionTimeout:连接超时时间,单位毫秒-->
<!-- maxThreads设定在监听端口的线程的最大数目,这个值也决定了服务器可以同时响应客户请求的最大数目.默认值为200 -->
<!-- connectionTimeout定义建立客户连接超时的时间.如果为-1,表示不限制建立客户连接的时间 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- redirectPort指定转发端口.如果当前端口只支持non-SSL请求,在需要安全通信的场命,将把客户请求转发至SSL的redirectPort端口-->
<!-- enableLookups如果设为true,表示支持域名解析,可以把IP地址解析为主机名.WEB应用中调用request.getRemoteHost方法返回客户机主机名.默认值为true -->
<Connector port="8009" enableLookups ="false" protocol="AJP/1.3" redirectPort="8443"/>
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
<!--引擎:表示指定service中的请求处理机,接收和处理来自Connector的请求.可以接收用户的http请求,并构建响应报文,而且可以在内部处理java程序的整个套间-->
<!-- defaultHost 指定缺省的处理请求的主机名,它至少与其中的一个host元素的name属性值是一样的 -->
<Engine name="Catalina" defaultHost="localhost">
3) Engine获得请求localhost/wcc/index.jsp,匹配它所拥有的所有虚拟主机Host
<!-- appBase 应用程序基本目录,即存放应用程序的目录-->
<!-- unpackWARs:如果此项设置为true,表示把WEB应用的WAR文件先展开为开放目录结构后再运行.如果设为false将直接运行为WAR文件,-->
<!-- autoDeploy:如果此项设为true,表示Tomcat服务处于运行状态时,能够监测appBase下的文件,如果有新有web应用加入进来,会自运发布这个WEB应用-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/wcc/index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/wcc的Context(如果匹配不到就把该请求交给路径名为””的Context去处理)
<!-- Context 表示运行在虚拟主机上的一个web应用程序,通常为WAR文件 -->
<!-- 一个<Host>可以包含多个<Context>元素.每个web应用有唯一的一个相对应的Context代表web应用自身.servlet容器为第一个web应用创建一个ServletContext对象. -->
<!-- docBase 应用程序的路径或者是WAR文件存放的路径 -->
<!-- path 表示此web应用程序的url的前缀,这样请求的url为http://localhost:8080/**** -->
<!-- reloadable 这个属性非常重要,如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载应用程序,我们可以在不重起tomcat的情况下改变应用程序 -->
<Context docBase="sample-demo" path="/sample-demo" reloadable="true" source="org.eclipse.jst.jee.server:sample-demo"/>
现在这个context都是配置conf/context.xml中。不建议配置在server.xml中,
因为server.xml是不可动态重加载的资源,服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。
而context.xml文件则不然,tomcat服务器会定时去扫描这个文件。一旦发现文件被修改(时间戳改变了),
就会自动重新加载这个文件,而不需要重启服务器。
系统拿到请求到具体的类和方法
7) path=”/wcc”的Context获得请求/index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
系统中具体的类和方法返回响应data给系统
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
系统给容器,容器返回给web
13)Connector把HttpServletResponse对象返回给客户browser
-------------知识点补充---------------
补充请求到系统的一个知识点。
目前我们的项目大多数是springmvc作为controller。如果项目是spring那么在请求进入到系统的时候,会对参数进行format。
具体使用HttpMessageConverter来进行转换。
流程如下
请求报文-->HttpInputMessage -->HttpMessageConverter -->项目
系统发出响应到浏览器也是类似
项目-->HttpMessageConverter -->HttpOutputMessage -->响应报文spring项目中默认加载 HttpMessageConveter 的6个实现类
分别是
StringHttpMessageConverter。
ByteArrayHttpMessageConverter。
ResourceHttpMessageConverter。
SourceHttpMessageConverter。
AllEncompassingFormHttpMessageConverter。
Jaxb2RootElementHttpMessageConverter。
如果配置了加入 jackson jar包后,启动的时候加载 第七个7个 HttpMessageConverter 的实现类
MappingJackson2HttpMessageConverter。
使用HttpMessageConverter的方式有@ResponseBody/@RequestBody,以及 ResponseEntity和 HttpEntity
spring首先根据请求头或者响应头的Accept属性选择对应的converter,如果没有找到,就会报错。
参考链接:https://blog.csdn.net/sky_100/article/details/77541968
https://www.cnblogs.com/yufeng218/p/6623329.html
https://www.cnblogs.com/xyhero/p/9343924.html