how tomcat works 5 servlet容器 下
上一节,我们主要说的是Wrapper容器,这一节我们说Context容器。
再重申一遍,一个Context容器可以包含多个Wrapper容器;
一个Wrapper容器就表示一个独立的servlet。
Context应用程序
这里我们得提出一个新的组件----映射器,它帮助servlet容器---在这一节汇总就是Context实例选择一个子容器(这里就是Wrapper实例)来处理某个指定的请求。
首先咱们得明确几点;
映射器的作用就是联系一个父容器与他的若干个子容器,一个父容器可以有若干个映射器,为什么?因为有这样可以支持不同的协议。
例如一个映射器用来支持http协议,另一个映射器支持https协议(话说,http与https有什么区别,我就说一点,那个s代表security,安全,采取了另一种形式的保密措施,一般银行,证券交易所用https)
Mapper接口如下,我们这节使用的是其实现类,SimpleContextMapper类
package org.apache.catalina;
public interface Mapper {
public Container getContainer();
public void setContainer(Container container);
public String getProtocol();
public void setProtocol(String protocol);
public Container map(Request request, boolean update);
}
各个方法的名字都起的很好,大家应该可以见名知意。
下面是这一节的uml类图
通过说明的uml图,大家可以看到我们熟悉的SimpleContext"含有"一个SimpleContextMapper,现在我们看看代码
public class SimpleContext implements Context, Pipeline {
public SimpleContext() {
pipeline.setBasic(new SimpleContextValve());
}
protected HashMap<String, Container> children = new HashMap<String, Container>();
protected Loader loader = null;
protected SimplePipeline pipeline = new SimplePipeline(this);
protected HashMap<String, String> servletMappings = new HashMap<String, String>();
protected Mapper mapper = null;
protected HashMap<String, Mapper> mappers = new HashMap<String, Mapper>();
private Container parent = null;
......
}
现在我来说说这个几个属性;
mapper这是一个Mapper类型的是属性,如果一个容器只有一个映射器的话,那么就默认是它;如果一个容器有若干个映射器(以应对不同的网络协议例如http与https)那么mapper就置为空;
mappers这是hashmap类型的,里面放置容器的若干个映射器,以映射器支持的协议作为key;
servletMapping 也是hashmap,里面存放的是一个个映射路径与子容器的映射关系;例如如果访问uri为/servletA,就对应servletA这个servlet;
childen又是一个hashmap,里面存放了servletA这个名字对于的子容器(在这里就是Wrapper)
测试类如下;
public final class Bootstrap2 {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
HttpConnector connector = new HttpConnector();
Wrapper wrapper1 = new SimpleWrapper();
wrapper1.setName("Primitive");
wrapper1.setServletClass("PrimitiveServlet");
Wrapper wrapper2 = new SimpleWrapper();
wrapper2.setName("Modern");
wrapper2.setServletClass("ModernServlet");
Context context = new SimpleContext();
context.addChild(wrapper1);
context.addChild(wrapper2);
Valve valve1 = new HeaderLoggerValve();
Valve valve2 = new ClientIPLoggerValve();
((Pipeline) context).addValve(valve1);
((Pipeline) context).addValve(valve2);
Mapper mapper = new SimpleContextMapper();
mapper.setProtocol("http");
context.addMapper(mapper);
Loader loader = new SimpleLoader();
context.setLoader(loader);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");
connector.setContainer(context);
try {
connector.initialize();
connector.start();
// make the application wait until we press a key.
System.in.read();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
我们先看看时序图
我直接从Context容器里的基础阀讲起,就是它SimpleContextValve(上一节的基础阀是SimpleWrapperValve)。基础阀之前的流程与上一节的内容一样,大家参照上一节。
public void invoke(Request request, Response response, ValveContext valveContext)
throws IOException, ServletException {
.....
Context context = (Context) getContainer();
// Select the Wrapper to be used for this Request
Wrapper wrapper = null;
try {
wrapper = (Wrapper) context.map(request, true);
}
catch (IllegalArgumentException e) {
badRequest(requestURI, (HttpServletResponse) response.getResponse());
return;
}
if (wrapper == null) {
notFound(requestURI, (HttpServletResponse) response.getResponse());
return;
}
// Ask this Wrapper to process this Request
response.setContext(context);
wrapper.invoke(request, response);
}
ok我们到SimpleContext的map方法里看看;
public Container map(Request request, boolean update) {
//this method is taken from the map method in org.apache.cataline.core.ContainerBase
//the findMapper method always returns the default mapper, if any, regardless the
//request's protocol
Mapper mapper = findMapper(request.getRequest().getProtocol());
if (mapper == null)
return (null);
// Use this Mapper to perform this mapping
return (mapper.map(request, update));
}
public Mapper findMapper(String protocol) {
// the default mapper will always be returned, if any,
// regardless the value of protocol
if (mapper != null)
return (mapper);
else
synchronized (mappers) {
return ((Mapper) mappers.get(protocol));
}
}
findMapper方法总是返回默认的那个映射器(前面我们已经说了,如果容器中只有一个映射器那它就是默认的,如果有多个,那么存储默认映射器的属性为空)如果有多个映射器就到mappers里去按照网络协议找;
找到映射器之后,就简单了
wrapper.invoke(request, response);
这就回到上一节那部分了,调用Wrapper的所有阀,直到基础阀(在这一节里,wrapper的管道里只有基础阀,之前的两个阀,装到了context的管道里),进入wrapper后调用allocate.......
how tomcat works 5 servlet容器 下的更多相关文章
- how tomcat works 五 servlet容器 上
servlet容器是用来处理请求servlet资源,并为Web客户端填充response对象的模块.在上一篇文章(也就是书的第四章)我们设计了SimpleContainer类,让他实现Containe ...
- Tomcat是一个Servlet容器?
"Tomcat是一个Servlet容器",这句话对于2019年的程序员应该是耳熟能详的. 单纯的思考一下这句话,我们可以抽象出来这么一段代码: class Tomcat { Lis ...
- 19、配置嵌入式servlet容器(下)
使用外置的Servlet 嵌入式Servlet容器:应用打成可执行的j ar 优点:简单.便携: 缺点:默认不支持JSP.优化定制比较复杂 使用定制器[ServerProperti ...
- httpServletRequest对象、filter、servlet、servlet容器、catalina、tomcat、以及web容器之间的关系
学习servlet的时候经常感到疑惑 HttpServletRequest是服务器创建的?还是servlet容器创建的? 过滤器是服务器创建的?还是servlet容器创建的? serlet容器和tom ...
- Web服务器(Apache)与Servlet容器(Tomcat)
之前一直比较迷惑Apache与Tomcat的关系,通过查询资料,有所了解,现记录于此. Apache与Tomcat 两者定位:Apache是HTTP Web服务器,Tomcat是Web容器. 有一个非 ...
- tomcat与jboss等容器的区别
1.JBoss 是 J2EE 应用服务器,而 Tomcat 只是一个 Servlet 容器,或者说是一个简单的 J2EE 应用服务器. JBoss 中的 Servlet 容器还是 Tomcat. 与 ...
- Web容器、Servlet容器、Spring容器、SpringMVC容器之间的关系
以下内容为个人理解,如有误还请留言指出,不胜感激! Web容器 web容器(web服务器)主要有:Apache.IIS.Tomcat.Jetty.JBoss.webLogic等,而Tomcat.Jet ...
- 为什么要有 Servlet ,什么是 Servlet 容器,什么是 Web 容器?
本文已收录至 https://github.com/yessimida/yes ,这里有我的所有文章分类汇总,欢迎 star! 以下代码相信大家都很熟悉,大学时学 Java Web 都写过这样的代码. ...
- springboot(七) 配置嵌入式Servlet容器
github代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service ...
随机推荐
- Scheme N皇后
(define (range n) (define (recur n) () '() (cons n (recur (- n ))))) (recur (- n ))) (define (flatte ...
- C语言如何在两个文件中访问同一个全局变量
方法一: 不使用头文件. 1.c 中 int var; 2.c 中 extern int var; 方法二: 使用头文件. 1.c 中 int var; 不必添加#include "1.h& ...
- Spark运行架构
http://blog.csdn.net/pipisorry/article/details/52366288 1. Spark运行架构 1.1 术语定义 lApplication:Spark App ...
- 即时通讯软件openfire+spark+smack
所以我基本上分为三篇文章来介绍此类软件的开发: 第一篇是关于XMPP 协议是啥,IM 是啥以及一个比较有名的开源实现,该开源实现包括三个部分(Spark.Smack和Openfire): 第二篇讲如何 ...
- [ExtJS5学习笔记]第九节 Extjs5的mvc与mvvm框架结构简介
本文地址:http://blog.csdn.net/sushengmiyan/article/details/38537431 本文作者:sushengmiyan ------------------ ...
- 【移动开发】AIDL中callback的实现
AIDL实现就可以在客户端中调用服务端的方法,并传递数据到服务端,也可以服务端传递数据过来:但是如果要从服务端去调用客户端的方法,那么就需要注册callback! 抄自和源码:http://zxl-o ...
- LInux last命令详解
命令简介: 该命令用来列出目前与过去登录系统的用户相关信息.指令英文原义:show listing of last logged in users 执行权限 :有些需要特殊权限 指令所在路径: ...
- 创建一个QT for Android的传感器应用应用程序(摘自笔者2015年将出的《QT5权威指南》,本文为试读篇)
这个手册描述了使用Qt Quick面访的方式在Android和ios设备上开发QtQuick应用程序的方法.我们使用Qt Creator实现一个QtQuick应用程序,这个应用程序基于加速器的值 ...
- Oracle EBS R12文件系统结构(学习汇总网上资料)
Oracle EBS R12在服务器端文件结构如下: 顶层目录下面分为 1)inst --–跟ebs整个实例(instance)相关的配置信息以及其他信息 2) db ---主要存储DB层的信息 ...
- Oracle EBS OM 主要API示例
1, Book order Oe_Order_Pub.Process_Order ( 1 , Fnd_Api.G_FALSE , Fnd_Api.G_FALSE , Fnd_Api.G_FALSE , ...