Mapper组件的核心功能是提供请求路径的路由映射,根据某个请求路径通过计算得到相应的Servlet(Wrapper)。这节看下Mapper的实现细节,包括Host容器、Context容器、Wrapper容器等的映射关系以及映射算法。

如果要将整个tomcat容器中所有的web项目以能够以Servlet级别组织起来,需要一个多层级的类似Map结构的存储空间。如上图,以Mapper作为映射的入口,按照容器等级首先会包含了N个Host容器的引用,然后每个Host会有N个Context容器的引用,最后每个Context容器包含N个Wrapper容器的引用。例如使用Mapper组件查找“tomcat.apache.org/tomcat-7.0-doc/search”,它首先会匹配name为“tomcat.apache.org”的Host,然后从中继续匹配name为“tomcat-7.0-doc”的Context,最后匹配name为“search”的Wrapper(Servlet)。

为了方便问题阐述,下面是一个简化后的Mapper映射关系的存储模型,暂时不考虑多版本Context。

①提供一个基础的键值对模型,name为容器的名称,object为具体的容器。

public class MapElement {
        public String name = null;
        public Object object = null;
 }

②Host映射模型,继承MapElement,且包含若干Context映射。

public class Host extends MapElement {
        public Context[] contexts = null;
}

③Context映射模型,继承MapElement,包含不同类型的Wrapper(servlet):默认Servlet、精确匹配Servlet、通配符Servlet和扩展Servlet。除此还有欢迎页资源和path。

public class Context extends MapElement {
        public String path = null;
        public String[] welcomeResources = new String[0];
        public Wrapper defaultWrapper = null;
        public Wrapper[] exactWrappers = new Wrapper[0];
        public Wrapper[] wildcardWrappers = new Wrapper[0];
        public Wrapper[] extensionWrappers = new Wrapper[0];
}

④Wrapper映射模型,继承MapElement。

public class Wrapper extends MapElement {
}

⑤Mapper类

public class Mapper{
    public Host[] hosts;
}

Mapper只要包含一个Host数组即可完成所有组件关系的映射。在tomcat启动时将所有Host容器和它的名字组成Host映射模型添加到Mapper对象中,每个Host下的Context容器和它的名字组成Context映射模型添加到对应的Host下,每个Context下的Wrapper容器和它的名字组成的Wrapper映射模型添加到对应的Context下。Mapper组件提供了对Host映射、Context映射、Wrapper映射的添加和移除的方法,在tomcat容器中添加或移除相应的容器时都要调用相应的方法维护这些映射关系。Mapper组件为了提高查找速度和效率,使用了二分搜索法查找,所以在添加时应按照字典序把Host、Context、Wrapper等映射排好序。

当tomcat启动稳定后,意味着这些映射都已经组织好,那么具体是如何查找对应容器的?

(一)Host的匹配,直接对Mapper中的Host映射数组进行忽略大小写的二分搜索查找。

(二)Context的匹配,对上面查找到的Host映射中的Context映射数组进行忽略大小写的二分搜索查找,这里有个比较特殊的情况是请求地址可以直接以Context名结束,例如http://tomcat.apache.org/tomcat-7.0-doc,另外一些则类似http://tomcat.apache.org/tomcat-7.0-do/index.html。另外,Context映射中的name对应的是Context容器的path属性。

(三)Wrapper的匹配,首先,尝试使用精确匹配法匹配精确类型Servlet的路径;然后,尝试使用前缀匹配通配符类型Servlet;接着尝试使用扩展名匹配通配符类型Servlet;最后,匹配成默认Servlet。

Tomcat在处理请求时对请求的路由分发全由Mapper组件负责,请求通过Mapper找到最终的处理Servlet或资源。而在tomcat中会有两种类型的Mapper,它们作用的范围不同,因为称为全局路由映射和局部路由映射。

tomcat请求路由映射核心组件Mapper的更多相关文章

  1. tomcat如何路由映射网址

    对于web容器来说,根据请求客户端路径路由到对应的资源属于其核心功能,假设用户在自己电脑上使用浏览器输入网址http://www.test.com/test/index.jsp,报文通过互联网网络到达 ...

  2. Oracle APEX 5.1 with Ords 17 in Tomcat 9–Error tips: 请求无法映射到任何数据库。请确保请求 URL 正确, 并且已正确配置 URL 到数据库的映射

    一次意外关机引发的血案 1.重新开机打开 tomcat 9, 一切正常 2.打开 ords,异常报错: 404 Not Found 请求无法映射到任何数据库.请确保请求 URL 正确, 并且已正确配置 ...

  3. TOMCAT 请求HTTP原理

    一.Tomcat是什么?Tomcat是一个Web应用服务器,同时也是一个Servlet/JSP容器.Tomcat作为Servlet容器,负责处理客户端请求,把请求传送给Servlet,并将Servle ...

  4. 二、freemarker.controller半自动静态化+Tomcat虚拟资源映射

    描述:本内容主要是讲2个tomcat之间同时共享一个静态话页面,统一入口是springMVC的一个controller,静态化的更新只需要传false.true.把完成的web项目放入a.b服务器To ...

  5. [Buffalo]ASP.NET MVC路由映射

    Asp.Net的路由系统旨在通过注册URl模版与物理文件之间的映射进而实现请求地址与文件路径之间的分离,但对于Asp.Net Mvc应用来说,请求的目标却是定义在某个Controller类型中的Act ...

  6. ASP.NET的路由系统:路由映射

    总的来说,我们可以通过RouteTable的静态属性Routes得到一个基于应用的全局路由表,通过上面的介绍我们知道这是一个类型的RouteCollection的集合对象,我们可以通过调用它的MapP ...

  7. Django-url路由映射与views逻辑处理

    一.URL路由映射 路由映射模块,主要完成url与views视图函数的映射.当一个url请求到来时,会按照这个模块中的url地址从上到下进行匹配,如果匹配成功,将执行映射试图中的函数:反之将返回404 ...

  8. 第三百零四节,Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器

    Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器 这一节主讲url控制器 一.urls.py模块 这个模块是配置路由映射的模块,当用户访问一个 ...

  9. 第二百六十八节,Tornado框架-路由映射之二级域名支持,html模板继承以及导入

    Tornado框架-路由映射之二级域名支持,html模板继承以及导入 二级域名路由映射add_handlers()设置二级域名路由映射 注意:二级域名需要结合服务器ip绑定域名 框架引擎 #!/usr ...

随机推荐

  1. 基于 HTML5 的 WebGL 3D 智能楼宇监控系统

    前言 智能监控的领域已经涉及到了各大领域,工控.电信.电力.轨道交通.航天航空等等,为了减少人员的消耗,监控系统必不可少.之前我写过一篇 2D 的智能地铁监控系统广受好评,突然觉得,既然 2D 的这么 ...

  2. AD域中添加了一个策略导致的问题

    AD域中添加了一个策略,导致浏览器报了一个错,点击下拉菜单选不了.查了资料说是添加信任站点就好,结果信任站点是置灰的,服务器有这个问题,本地是好的. 解决办法:本地服务器有个ie增强设置,关掉就好.

  3. HTTPS介绍

    超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...

  4. break 与 continue

    1.break ①只有一层循环时,作用是跳出循环语句,执行后面的代码. ②break存在于循环嵌套的内层循环时,只能跳出内层循环,如果想要跳出外层循环,需要对外层循环添加标记. 2.continue ...

  5. Oracle VM VirtualBox虚拟机内Linux系统硬盘扩容步骤(CentOS6.5)

    1.首先获取要扩容的虚拟机的 UUID VBoxManage 改命令在C:\Program Files\Oracle\VirtualBox目录内,可先添加该目录到环境变量.C:\Users\yzkj- ...

  6. WEB中间件--tomcat爆破,burp和python脚本

    1.tomcat 用burpsuit进行弱口令爆破 先抓包 发送到inturder payload type 选择custom iterater 第一个payload选用户名文件,第二个payload ...

  7. redis锁处理并发问题

    redis锁处理并发问题 redis锁处理高并发问题十分常见,使用的时候常见有几种错误,和对应的解决办法. set方式 setnx方式 setnx+getset方式 set方式 加锁:redis中se ...

  8. OkHTTPClient

    一,OKHttp介绍 okhttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和Leak ...

  9. Mybatis自动生成实体类和实体映射工具

    Mybatis Mysql生成实体类 用到的Lib包: mybatis-generator-core-1.3.2.jarmysql-connector-java-5.1.30.jar 1. 创建一个文 ...

  10. 谈谈Circuit Breaker在.NET Core中的简单应用

    前言 由于微服务的盛行,不少公司都将原来细粒度比较大的服务拆分成多个小的服务,让每个小服务做好自己的事即可. 经过拆分之后,就避免不了服务之间的相互调用问题!如果调用没有处理好,就有可能造成整个系统的 ...