学习Tomcat(五)之Context和Wrapper容器
前面的文章中,我们介绍了Tomcat的Engine和Host容器,我们知道一个Tomcat最多只有一个Engine容器,一个Engine容器可以包含多个Host容器,请求中的不同的Host对应不用的Host容器。本章我们会介绍Tomcat的另外两个容器:Context容器和Wrapper容器。一个Host容器可以包含多个Context容器:同一个Host下面可以包含多个应用,每个应用对应一个Context容器。一个Context容器又可以包含多个Wrapper容器:每个Wrapper容器包含一个Servlet容器,意味着Tomcat允许一个应用有多个servlet实现。
Tomcat请求流程
我们现在知道Tomcat最重要的组件是连接器和四种类型的容器,下面的图展示了Tomcat的一次请求是如何在连接器和四种容器之间流转的,假设Http请求头为"GET /appB/servletB/some-url HTTP/1.1 Host: www.krishnan.com",当请求访问到Tomcat容器时,会经过以下流转步骤:
- Tomcat的连接器监听SocketServer,发现这个请求,按照指定的协议和IO方式处理请求Socket消息,解析Socket为对应的Request实体,并提供回写报文的Response实体。
- 连接器将Request/Response交给Engine容器,Engine容器存储了请求域名和Host容器之间的映射关系。比如"www.krishnan.com"域名对应于krishnan_webapps Host容器。
- Engine容器将请求交给对应的Host容器,Host容器开始解析请求中的路径,如果配置了路径和应用之间的关系,比如"/appB"对应于appB Context容器,Host容器会安装配置将请求交给对应应用的Context容器。
- Host容器解析路径并将应用交给Context容器之后,如果一个应用有多个Servlet,那么这个应用的Context容器也会包含多个Wrapper容器,我们可以通过路径来将不同的请求映射到不同的Servlet容器。比如图中的"/servletB"对应servletB Wrapper容器,Context容器将请求交给Wrapper容器。
- Context容器按照路径将请求交给对应的Wrapper容器,Wrapper容器会加载对应的Servlet实现类,调用servlet实现类中的逻辑处理Request并将处理结果写入Response中。

Context容器
我们在配置Tomcat应用程序的时候,总是需要配置一个web.xml文件,这个文件就是Context容器去解析的。tomcat默认的web.xml的配置如下所示,该配置中配置了两个WrapperContext,分别对应于两个Servlet配置。在web.xml中,我们经常可以看到listener标签,主要是用于监听Context容器的声明周期事件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<request-character-encoding>UTF-8</request-character-encoding>
<response-character-encoding>UTF-8</response-character-encoding>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- The mappings for the JSP servlet -->
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Wrapper容器
Wrapper容器是最小的容器,每个Wrapper都可以对应一个Servlet的实例。当请求转发到Wrapper容器之后,wrapper容器在调用Pipeline方法之后,会使用特定的类加载器去加载servlet类,对servlet进行实例化和初始化,然后将请求交给servelt的service方法进行处理。
我们常见的Spring的DispatchServlet是线程安全的,所以Tomcat不需要保证Servlet的并发安全。对于非线程安全的servlet,则可以通过SingleThreadModel来保证多请求下servlet的正常运行。
Wrapper容器的主要作用就是载入servlet类并进行实例化,并调用service方法。当第一次请求某个servlet类的时候,Wrapper容器会载入servlet类。Tomcat提供了专门的类加载器用于加载servlet,关于这个类加载器我会在我的其它文章中介绍。
Wrapper容器的基本阀门StandardWrapperValve还会在调用servelt容器之前调用用户配置的过滤器链Filter。
我是御狐神,欢迎大家关注我的微信公众号:wzm2zsd

本文最先发布至微信公众号,版权所有,禁止转载!
学习Tomcat(五)之Context和Wrapper容器的更多相关文章
- Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition Property animation系统还提供了对ViewGroup中的View改变 ...
- Docker学习笔记五:Docker生成jenkins容器,支持Java Web项目持续集成、持续部署
一.创建jenkins容器: 1.拉取jeknin镜像 sudo docker pull jenkins 2.创建一个jenkins目录 sudo mkdir /jenkins 3.在jenkins目 ...
- 深入理解Tomcat系列之五:Context容器和Wrapper容器
前言 Context容器是一个Web项目的代表,主要管理Servlet实例,在Tomcat中Servlet实例是以Wrapper出现的.如今问题是怎样才干通过Context容器找到详细的Servlet ...
- Tomcat Context容器和Wrapper容器
前言 Wrapper容器 前言 Context容器是一个Web项目的代表,主要管理Servlet实例,在Tomcat中Servlet实例是以Wrapper出现的,现在问题是如何才能通过Context容 ...
- 学习Tomcat(一)之容器概览
Tomcat是Apache软件基金会的一个顶级项目,由Apache.Sun和其它一些公司及个人共同开发,是目前比较流行的Web服务器之一.Tomcat是一个开源的.小型的轻量级应用服务器,具有占用系统 ...
- 学习Tomcat(六)之类加载器
通过前面的文章我们知道,Tomcat的请求最终都会交给用户配置的servlet实例来处理.Servlet类是配置在配置文件中的,这就需要类加载器对Servlet类进行加载.Tomcat容器自定义了类加 ...
- 烂泥:学习tomcat之通过shell批量管理多个tomcat
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 公司的业务是使用tomcat做web容器,为了更有效的利用服务器的性能,我们一般部署多个 ...
- Tomcat学习—Tomcat的简介和目录以及配置文件介绍(Windows环境)
tomcat学习(8) 版权声明:本文为博主原创文章,未经博主允许不得转载. 今天学习TOMCAT,主要学习的是Tomcat的目录结构,配置文件! 1:Tomcat简介 Tomcat 服务器是一个免费 ...
- Docker学习(五): 仓库与数据管理
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...
随机推荐
- linux shell 脚本输入参数解析
文件名: test.sh #!/bin/bash para="para: "; while [ $# -ge 2 ] ; do case "$1" in --a ...
- Mybatis原理和代码剖析
参考资料(官方) Mybatis官方文档: https://mybatis.org/mybatis-3/ Mybatis-Parent : https://github.com/mybatis/par ...
- IMO 2021 第一题题解及相关拓展问题分析
IMO 2021 第 1 题: 设整数 n ≥ 100.伊凡把 n, n + 1, ..., 2n 的每个数写在不同的卡片上.然后他将这 n + 1 张卡片打乱顺序并分成两堆.证明:至少有一堆中包含两 ...
- Electron团队为什么要干掉remote模块
Electron团队提供remote模块给开发者, 主要目的是为了简化渲染进程和主进程互访的难度, 这个目的却是达到了. 但也带来了很多问题, 归纳起来主要分为以下四点: 第一:它很慢 通过remot ...
- NX二次开发-使用NXOPEN C++向导模板做二次开发
版本 NX9+VS2012 1.怎么往VS软件里添加VC,C#,VB向导模板 先到NX安装目录下UGOPEN文件夹里找到这三个文件夹 拷贝到VS的安装目录下 这里有几个注意事项,VS2017,VS20 ...
- 源码解析.Net中Middleware的实现
前言 本篇继续之前的思路,不注重用法,如果还不知道有哪些用法的小伙伴,可以点击这里,微软文档说的很详细,在阅读本篇文章前,还是希望你对中间件有大致的了解,这样你读起来可能更加能够意会到意思.废话不多说 ...
- Servlet学习笔记(一)之Servlet原理、初始化、生命周期、结构体系
Servlet是用java语言编写的应用到Web服务器端的扩展技术,与java对象的区别是,Servlet对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持(以下会介绍原因, ...
- Spring BeanDefinition
定义 /** * A BeanDefinition describes a bean instance, which has property values, * constructor argume ...
- mybaits源码分析--binding模块(五)
一.binding模块 接下来我们看看在org.apache.ibatis.binding包下提供的Binding模块 ,binding其实在执行sqlSession.getMapper(UserMa ...
- TDSQL(MySQL版)之DB组件升级
随着数据库产品的更新迭代,修复bug等等,产品避免不了会出现升级的需求.TDSQL(MysqL版)也会有这方面的需求.接下来我就说说如何对现有TDSQL(MySQL版)集群组件进行升级,而不影响业务. ...