一个container是一种模块,处理对servlet的请求并且返回response对象给web client端. 一个container由org.apache.catalina.Container接口定义.一共有四种类型的container:engine,host,context和wrapper.本章将会介绍context和wrapper,剩下两种会在13章中介绍.本章开始于对container接口的讨论,接着讲述在container中pipelining的原理.然后具体介绍wrapper和context接口.本章结尾给出了两个应用程序,分别实现了简单的wrapper和context.
1 Container接口
Container必须实现org.apache.catalina.Container接口。有四种不同概念层次的container,
Engine:代表整个Catalina servlet引擎。
Host:代表一个虚拟host,其中包含若干context。
Context:代表一个web application,其中可包含若干wrapper。
Wrapper:代表一个独立的servlet。
在org.apache.catalina.core包中,StandardEngine, StandardHost, StandardContext, StandardWrapper是四个标准实现。
这四种引擎不都是必须的。比如本章的第一个application只包含一个wrapper。第二个application包含一个context和wrapper。
一个Container可以有0个或多个低一层的child container。比如,一个context可以有若干个wrapper,host可以有若干context。因为wrapper在最底层,所以是没有child container的。加减一个孩子的方法在接口中有定义,
public void addChild(Container child)
public void removeChild(Container child)
Container接口还可以查找child container,
public Container findChild(String name)
public Container[ ] findChildren()
Container还有一些辅助性的组件,比如Loader, Logger, Manager, Realm, Resources,后面几章会有介绍。Container接口对这些组件有相应的get set方法。
需要强调的是,Tomcat管理员可以在configuration文件(server.xml)中设置container的性能。这是通过container中的pipeline和一组valve(阀门,管子)来实现的。下一节“Pipelining Tasks”会有讨论。
2、Pipelining Tasks
这部分内容讲解了connector调用的container的invoke方法都具体做了什么。这一节会介绍4个相关的接口:Pipeline, Valve, ValveContext, Contained。他们都在包org.apache.catalina中。
Pipeline包含Container调用的所有的任务。一个valve代表一个具体的任务。在container的pipeline中有一个基本的valve,但是你可以加入任意多的valve。valve的个数是指后加入的个数,并不包括那个基本的valve。有趣的是,valve可以动态的加入到Tomcat的configuration文件(server.xml)中。
pipeline和valve理解起来很象是servlet filter。pipeline是一个filter chain,每一个valve是一个filter。一个valve的任务完成后,下一个valve的任务会被调用。那个basic valve总是被最后调用。可以想象,这个过程可以用下面的伪代码描述:
for (int n=0;n<valve.length;n++) {
valve[n].invoke(...);
}
basicValve.invoke(...);
但是,Tomcat并没有用上述方式,而是引入了org.apache.catalina.ValveContext接口。Container的invoke()方法被调用时,里面调用了pipeline的invoke()方法。pipeline里的invoke方法有着和Container中一样的定义:
public void invoke(Request request, Response response) throws...
pipeline作为一个属性关联到一个Container对象。
现在pipeline需要确定每一个关联到他的valve都被执行一次。pipeline通过ValveContext接口的一个实例来完成这个任务。ValveContext作为pipeline的一个内部类实现,所以他可以访问到pipeline中的每一个属性。
ValveContext中最重要的方法是:
public void invokeNext(Request request, Response response) throws....
Valve中的invoke()方法为:
public void invoke(Request request, Response response, ValveContext vc)....
valveContext的invokeNext先调用第一个valve的invoke方法,并且他自己传给valve的invoke方法,然后再由valve的invoke来调用valveContext的invokeNext()。
简言之,valvecontext, pipeline, valve 类之间的关系如下:
class pipeline {
valve[] avalve;
function invoke(request, response) {
new valvecontext().invokeNext();
}
inner class valvecontext {
invokeNext(request, response) {
avalve[i].invoke(request, response, this);
}
}
}
class valve {
invoke(request, response, valvecontext) {
// TO DO ...
this.invokeNext(request, response);
}
}
pipeline和container的关系是:pipeline是container的一个成员变量
用这种方式,多个valve依次被调用。
==========================================
PS: 上述3个类 和 container 又有什么关系?
==========================================
3、The Wrapper Application
这里需要提一下将在12章中介绍的Context接口。这个接口代表了一个web application。他通常含有多个wrapper作为他的孩子。重要的方法包括addWrapper, createWrapper...
转入正题。
本章wrapper的一个简单的实现是 ex05.pyrmont.core.SimpleWrapper。包含了一个Pipeline(ex05.pyrmont.core.SimplePipeline), 一个Loader(ex05.pyrmont.core.SimpeLoader)来加载一个servlet。
这个pipeline中包含了一个基本的valve(SimpleWrapperValve)和两个additional的valve(ClientIPLoggerValve , HeaderLoggerValve)。
这个loader的工作过程 和 前几章的加载类的过程完全一样。只是功能给抽离出来而已。
SimpeWrapperValve的重要作用。
作为基本的valve。SimpleWrapperValve的做用是 调用 servlet的service方法。方法调用的地方是在valve 的 invoke方法中。
另外两个附加的valve,作用就是在simplewrappervalve调用invoke之前,做点事情。(filter的功能应该就是在这里实现的吧)。
ex05.pyrmont.startup.Bootstrap1 启动类的实现如下:
HttpConnector connector = new HttpConnector();//新建连结器
Wrapper wrapper = new SimpleWrapper();//新建容器,初始化方法会设置basicValve
wrapper.setServletClass("ModernServlet");//设置容器中的servlet
Loader loader = new SimpleLoader();//新建类装载器
Valve valve1 = new HeaderLoggerValve();//新建additional valve
Valve valve2 = new ClientIPLoggerValve();//新建additional valve
wrapper.setLoader(loader);// 设置容器的类装载器
((Pipeline) wrapper).addValve(valve1);//设置容器的additional valve
((Pipeline) wrapper).addValve(valve2);//设置容器的additional valve
connector.setContainer(wrapper);//设置连结器对应的容器
try {
connector.initialize();
connector.start();
}
catch (Exception e) {
}
4、 The Context Application
这个应用程序展示了包含两个wrapper的容器(也即两个servelt)。一个以上的wrapper就需要引入一种新的组件,叫做mapper。mapper组件的作用是根据特定的request来选择哪个wrapper来处理。
mapper的接口定义如下:
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);//用来返回一个child container
}
回忆一下,从container层次的角度来说,wrapper在最底层,context在wrapper层之上。
本章中这个context的例子,用了一个loader和两个valves。这三个组件都和context相关联。这样他们可以被底层的wrapper所共享。这个context被指定为connector的容器。下面列出的是这个容器(即context)的执行顺序:
a. context有一个pipeline。这个container的invoke方法调用pipeline的invoke方法。
b. pipeline的invoke方法调用所有context的valve的invoke方法。
c. 在context层的basic valve中,用mapper找到一个child wrapper来处理特定的请求
d. 找到了child wrapper后,wrapper的各个valve在被依次调用。
ex05.pyrmont.core.SimpleContextValve
ex05.pyrmont.core.SimpleContextMapper
ex05.pyrmont.core.SimpleContext
这三个类分别就是 context层的basic valve、context的孩子wrapper的影射、context层 的具体的实现类。
启动类bootstrap2.java的主要部分如下:
HttpConnector connector = new HttpConnector();//新建连结器
Wrapper wrapper1 = new SimpleWrapper();//新建一个wrapper
wrapper1.setName("Primitive");
wrapper1.setServletClass("PrimitiveServlet");
Wrapper wrapper2 = new SimpleWrapper();//新建另一个wrapper
wrapper2.setName("Modern");
wrapper2.setServletClass("ModernServlet");
Context context = new SimpleContext();//新建一个context
context.addChild(wrapper1);//为context添加一个wrapper
context.addChild(wrapper2);//为context再添加一个wrapper
Valve valve1 = new HeaderLoggerValve();//新建valve
Valve valve2 = new ClientIPLoggerValve();//新建valve
((Pipeline) context).addValve(valve1);// context层添加valve
((Pipeline) context).addValve(valve2);// context层添加valve
Mapper mapper = new SimpleContextMapper();//新建一个mapper
mapper.setProtocol("http");
context.addMapper(mapper);
Loader loader = new SimpleLoader();//新建一个loader
context.setLoader(loader);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");//建立wrapper的mapping
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();
}
运行启动类后,在ie中请求 http://localhost:8080/Modern http://localhost:8080/Primitive 。容器context接受请求。在执行完context层的valve后,会根据 /Modern /Primitive 来找到对应的wrapper,来继续执行,进而调用具体的servlet。
-- 完毕 欢迎各位同仁共同交流:)
相关推荐
《How Tomcat Works》是一份深入探讨Apache Tomcat工作原理的重要资源,包含了英文PDF文档、中文HTML翻译以及源代码,旨在帮助读者理解Tomcat服务器的内部运作机制。这份资料是IT从业者,特别是Java Web开发者、系统...
在《How Tomcat Works》这本书中,作者详细剖析了Tomcat的内部工作机制,特别是对Tomcat的4.1.12和5.0.18两个版本的源代码进行了深入的分析。本书通过逐步揭示Tomcat的各个组件,帮助读者理解Tomcat的内部结构和运作...
《How Tomcat Works》这本书及其源代码,为开发者提供了深入理解Tomcat内部工作机制的宝贵资源。本文将基于提供的文件名"如何Tomcat工作",结合Tomcat的工作流程,深入探讨其核心组件和功能。 1. **Tomcat架构概述*...
通过阅读和理解Tomcat的源代码,可以深入了解其内部工作流程,从而提升自定义扩展和调试的能力。《HowTomcatWorksApps.zip》这个压缩文件可能包含了一些示例应用或代码片段,供读者实践和研究。 总的来说,《How ...
4. **JSP编译**:Tomcat在首次遇到JSP页面时,会将其转换为Servlet源代码并编译成.class文件。这个过程涉及JSP标签库、EL(Expression Language)和JSTL(JavaServer Pages Standard Tag Library)的解析。 5. **...
《How Tomcat Works》是一本深入解析Apache Tomcat服务器内部工作原理的重要参考资料,它提供了对Tomcat架构的全面理解,包括其设计、配置和优化。这本书的中文版和英文版都为读者提供了便利,无论你是母语为中文...
《HowTomcatWorks》是一本深入解析Apache Tomcat工作原理的书籍,中文版的发布使得更多的中国开发者能够理解和掌握这款广泛应用的开源Java Servlet容器的工作机制。Tomcat是Apache软件基金会Jakarta项目的一部分,它...
作为一本面向中高级开发者的书籍,《how tomcat works》不仅为读者提供了丰富的理论知识,还提供了许多实用的示例和源代码分析,帮助读者更好地理解概念,并应用到实践中去。例如,书中提到了如何为Tomcat实现自定义...
"how-tomcat-works-master_howtomcatworks_"是一个关于Tomcat工作原理的源码分析项目,经过整理后可以在IntelliJ IDEA中直接运行,为开发者提供了一手的实践平台。 首先,我们要了解Tomcat的核心组件。Tomcat主要由...
"HowTomcatWorks"项目,正如其名,旨在帮助开发者了解Tomcat的工作原理,通过源代码分享,使我们有机会深入探究这个强大的服务器内部机制。 1. **Tomcat架构概览** Tomcat的架构设计分为几个主要部分:Catalina...
《深入剖析Tomcat》这本书是Java开发者们了解和学习Tomcat服务器的重要参考资料,它详细解析了Tomcat的工作原理和内部机制。随书源码则为读者提供了实践和探索的平台,帮助读者更深入地理解书中的理论知识。下面将...
而"HowTomCatWorks"很可能是源码的目录或者解压后的源代码文件,读者可以直接查看和分析Tomcat的源代码,这对于深入学习和定制Tomcat非常有帮助。 总的来说,这份资料对于想要深入了解Tomcat、提升服务器性能的...
而"jakarta-tomcat-4.1.12-src.zip"和"jakarta-tomcat-5.0.18-src.zip"则包含了对应版本的源代码,这些源代码对于学习Tomcat的架构设计、模块划分以及代码实现非常关键。同时,源码包通常还包括构建脚本,读者可以...
《译How Tomcat Works(第四章)》这篇文章深入解析了Apache Tomcat服务器的工作原理,主要聚焦于Tomcat的内部机制,对于理解Web应用容器的运行方式具有重要意义。Tomcat是Java Servlet和JavaServer Pages(JSP)...
【标题】"how tomcat works和jetty-src和tomcat7-src" 提及了三个关键概念:Tomcat的工作原理、Jetty源代码以及Tomcat 7的源代码。这些是Java Web服务器领域的核心元素,主要涉及到如何处理HTTP请求、部署Web应用...
how tomcat works 中文版 1-20章 现在全了 不光前四章 感谢 macula7 的空间 http://hi.baidu.com/macula7/blog/item/81fd14cbb7059f8dc81768d8.html 其翻译了 how tomcat works 还写了tomcat源代码学习
《How Tomcat Works》是一份详细阐述Tomcat工作原理的资源,包含英文版电子书和源代码。Tomcat是Apache软件基金会的项目,它是一个开源的Java Servlet容器,广泛用于部署Java Web应用程序。这份资料旨在帮助读者深入...
本篇文章将深入剖析"HowTomcatWorks",帮助读者全面理解Tomcat的内部工作机制。 1. **Tomcat架构概述** Tomcat由一系列组件构成,包括Catalina(核心Servlet容器)、Jasper(JSP引擎)、 Coyote(HTTP/HTTPS连接器...