- 浏览: 68525 次
- 性别:
- 来自: 成都
最新评论
-
qiaohhgz:
public static void String chang ...
一图和几句话解决java参数传值问题 -
ocaicai:
虽然我看懂了你的意思,但是我依然觉得表达得有些欠妥!
一图和几句话解决java参数传值问题 -
ql0722:
特别赞同第二条第三条
如果我再年轻几岁 -
zzc_zj:
很好的知识点,学习了
数据库查询select原理 -
dai03070609:
[url][/url][flash=200,200][/fla ...
数据库查询select原理
Chapter 5: Container
一个容器是一个为servlet处理请求和给客户端填充response对象的模块。一个容器可以用
org.apache.catalina.Container接口表示。这里有四种类型的容器:Engine, Host, Context 和Wrapper。这章包含了Context和Wrapper。把其它两个容器放在后面第十三章讲解。
The Container Interface
一个容器必须实现了org.apache.catalina.Container。你看到了在第四章中,你传递一个Container实例给连接器的toContainer方法,这样连接器可以调用容器的invoke方法。回顾下面的Bootstrap类的代码:
第一件要注意的事情是在Catalina里面的容器在不同概念层次上的划分有下面四种类型的容器:
Engine:
Represents the entire Catalina servlet engine. (代表整个Catalina的servlet engine)
Host:
Represents a virtual host with a number of contexts.(代表一个有许多context的虚拟主机)
Context:
Represents a web application. A context contains one or more wrappers.(代表一个web应用,一个context包含一个或更多wrapper)
Wrapper:
Represents an individual servlet.(代表一个单独的servlet)
每个概念上的层次用org.apache.catalina包中的一个接口表示。这些接口是:Engine, Host, Context和 Wrapper。这四个接口都继承了Container接口。这四个容器的标准实现分别是:
StandardEngine, StandardHost, StandardContext和StandardWrapper。很具有代表性,他们都是org.apache.catalina.core包的一部分。
一个能完成应用功能的Catalina的部署不需要包含所有的这四种容器。例如:在这章的第一个应用程序的容器模块只包含了一个wrapper。第二个应用程序是一个拥有一个context和一个wrapper的容器模块。这章的应用程序中既没有host也没有engine。
一个容器可以有0个或更多低层次的的子容器。例如:一个context通常有一个或更多wrapper,一个host可以有0个或更多context。但是,一个wrapper是位于层次结构的最底层,他就不能包含子容器。增加一个子容器到一个容器中,你使用Container接口的addChild方法:
从一个容器中移除一个子容器使用Container接口的removeChild方法:
此外,Container接口支持使用findChild和FindChildren方法找到一个容器的一个子容器和一个容器的所有子容器集合:
一个容器也可以包含很多个像后面要讲到的支持组件:Loader, Logger, Manager, Realm和Resources.这里不得不提一下Container接口提供的get和set方法来把容器自己和组件联系起来的方法:getLoader 和setLoader, getLogger 和setLogger, getManager 和
setManager, getRealm 和setRealm,getResources 和 setResources。
更有趣的是,Container接口通过这种方式来指定:在部署的时候,一个Tomcat的管理员(administrator)通过修改配置文件(server.xml)决定一个容器是完成什么事情的。而这又是通过在一个容器中引入一个pipeline和一套valve来实现的。
注意:Tomcat 4 的Container接口和Tomcat 5的稍有一点不同。例如:Tomcat 4 接口有一个map方法,而在Tomcat 5中就没有。
Pipelining Tasks
一个pipeline包含了容器将要调用的任务(tasks)。一个valve代表一个具体的任务。一个容器的pipeline有一个(basic valve)基本的valve(阀),但是你还是可以添加任意多你想要添加的valve。valve的数量是由增加的valve的数量决定,但不包含basic valve。有趣的是,valve可以通过修改Tomcat的配置文件(server.xml)来动态地添加。
如果你了解servlet的filter,你就不难想象一个pipeline的valve是怎么工作的了。一个pipeline就像是一个filter chain,而每一个valve就是一个filter。就像filter一样,一个valve可以处理传递给它的request和response对象。当一个valve完成了处理工作,它就调用在pipeline中的下一个valve。而basic valve总是在最后被调用。
一个容器可以有一个pipeline。当一个容器的invoke方法被调用,容器传递处理任务到它的pipeline,这个pipeline就调用它的第一个valve,然后调用它后面的valve,依次调用到最后。
直到在pipeline中再也没有valve。你可以想象的到,你可以跟着下面的pipeline的invoke方法的伪代码:
但是,Tomcat的设计者选择了不同的方式,通过引入了org.apache.catalina.ValveContext接口。下面介绍它怎么工作的。
一个容器当它的invoke方法被连接器调用时,它打算做什么事情不能通过(hard code)硬编码实现。而是容器调用它的pipeline的invoke方法。Pipeline接口的invoke方法和Container接口的invoke方法相同:
下面是Container接口的invoke方法在org.apache.catalina.core.ContainerBase类的实现
pipeline是容器内部的Pipeline接口的实例。
现在,pipeline必须确认所有的valve被添加,basic valve必须被调用一次。pipeline通过创建一个ValveContext接口的实例来完成valve的添加确认。ValveContext是作为一个pipeline的内部类实现的,所以ValveContext可以访问pipeline的所有成员。ValveContext接口的最重要的方法是invokeNext方法:
创建了一个ValveContext实例后,pipeline调用ValveContext的invokeNext方法。ValveContext将首先调用pipeline中的第一个valve,然后第一个valve在它完成了任务前将调用下一个valve。ValveContext把它自己传递给每一个valve,所以valve可以调用ValveContext的invokeNext方法。
一个valve的invoke方法的实现:
org.apache.catalina.core.StandardPipeline类是在所有容器的Pipeline的实现。在Tomcat 4中,这个类有一个叫做StandardPipelineValveContext的实现了ValveContext接口的内部类。
invokeNext方法使用下标(subscript)和状态(stage)来明确指出哪一个valve被调用过。当在pipeline的invoke方法第一个valve被调用时,下标值是0,状态值是1。因此,第一个valve(数组下标是0)被调用。在pipeline中的第一个valve接收ValveContext实例和调用它的invokeNext方法。这时,下标值是1,当然第二个valve被调用,以此类推。
当最后一个valve的invokeNext方法被调用时,下标值是等于valve的数量。最后,basic valve被调用。
Tomcat 5从StandardPipeline中移除了StandardPipelineValveContext类,而依靠org.apache.catalina.core.StandardValveContext。
你可以看见Tomcat 4中的StandardPipelineValveContext类和Tomcat 5 中的StandardValveContext类相似。
下面们将要详细讨论Pipeline, Valve和 ValveContext接口:
谢谢指正。这个措词是不恰当。抽象层面的东西。
一个容器是一个为servlet处理请求和给客户端填充response对象的模块。一个容器可以用
org.apache.catalina.Container接口表示。这里有四种类型的容器:Engine, Host, Context 和Wrapper。这章包含了Context和Wrapper。把其它两个容器放在后面第十三章讲解。
The Container Interface
一个容器必须实现了org.apache.catalina.Container。你看到了在第四章中,你传递一个Container实例给连接器的toContainer方法,这样连接器可以调用容器的invoke方法。回顾下面的Bootstrap类的代码:
HttpConnector connector = new HttpConnector(); SimpleContainer container = new SimpleContainer(); connector.setContainer(container);
第一件要注意的事情是在Catalina里面的容器在不同概念层次上的划分有下面四种类型的容器:
Engine:
Represents the entire Catalina servlet engine. (代表整个Catalina的servlet engine)
Host:
Represents a virtual host with a number of contexts.(代表一个有许多context的虚拟主机)
Context:
Represents a web application. A context contains one or more wrappers.(代表一个web应用,一个context包含一个或更多wrapper)
Wrapper:
Represents an individual servlet.(代表一个单独的servlet)
每个概念上的层次用org.apache.catalina包中的一个接口表示。这些接口是:Engine, Host, Context和 Wrapper。这四个接口都继承了Container接口。这四个容器的标准实现分别是:
StandardEngine, StandardHost, StandardContext和StandardWrapper。很具有代表性,他们都是org.apache.catalina.core包的一部分。
一个能完成应用功能的Catalina的部署不需要包含所有的这四种容器。例如:在这章的第一个应用程序的容器模块只包含了一个wrapper。第二个应用程序是一个拥有一个context和一个wrapper的容器模块。这章的应用程序中既没有host也没有engine。
一个容器可以有0个或更多低层次的的子容器。例如:一个context通常有一个或更多wrapper,一个host可以有0个或更多context。但是,一个wrapper是位于层次结构的最底层,他就不能包含子容器。增加一个子容器到一个容器中,你使用Container接口的addChild方法:
public void addChild(Container child);
从一个容器中移除一个子容器使用Container接口的removeChild方法:
public void removeChild(Container child);
此外,Container接口支持使用findChild和FindChildren方法找到一个容器的一个子容器和一个容器的所有子容器集合:
public Container findChild(String name); public Container[] findChildren();
一个容器也可以包含很多个像后面要讲到的支持组件:Loader, Logger, Manager, Realm和Resources.这里不得不提一下Container接口提供的get和set方法来把容器自己和组件联系起来的方法:getLoader 和setLoader, getLogger 和setLogger, getManager 和
setManager, getRealm 和setRealm,getResources 和 setResources。
更有趣的是,Container接口通过这种方式来指定:在部署的时候,一个Tomcat的管理员(administrator)通过修改配置文件(server.xml)决定一个容器是完成什么事情的。而这又是通过在一个容器中引入一个pipeline和一套valve来实现的。
注意:Tomcat 4 的Container接口和Tomcat 5的稍有一点不同。例如:Tomcat 4 接口有一个map方法,而在Tomcat 5中就没有。
Pipelining Tasks
一个pipeline包含了容器将要调用的任务(tasks)。一个valve代表一个具体的任务。一个容器的pipeline有一个(basic valve)基本的valve(阀),但是你还是可以添加任意多你想要添加的valve。valve的数量是由增加的valve的数量决定,但不包含basic valve。有趣的是,valve可以通过修改Tomcat的配置文件(server.xml)来动态地添加。
如果你了解servlet的filter,你就不难想象一个pipeline的valve是怎么工作的了。一个pipeline就像是一个filter chain,而每一个valve就是一个filter。就像filter一样,一个valve可以处理传递给它的request和response对象。当一个valve完成了处理工作,它就调用在pipeline中的下一个valve。而basic valve总是在最后被调用。
一个容器可以有一个pipeline。当一个容器的invoke方法被调用,容器传递处理任务到它的pipeline,这个pipeline就调用它的第一个valve,然后调用它后面的valve,依次调用到最后。
直到在pipeline中再也没有valve。你可以想象的到,你可以跟着下面的pipeline的invoke方法的伪代码:
// invoke each valve added to the pipeline for (int n=0; n<valves.length; n++) { valve[n].invoke( ... ); } // then, invoke the basic valve basicValve.invoke( ... );
但是,Tomcat的设计者选择了不同的方式,通过引入了org.apache.catalina.ValveContext接口。下面介绍它怎么工作的。
一个容器当它的invoke方法被连接器调用时,它打算做什么事情不能通过(hard code)硬编码实现。而是容器调用它的pipeline的invoke方法。Pipeline接口的invoke方法和Container接口的invoke方法相同:
public void invoke(Request request, Response response) throws IOException, ServletException;
下面是Container接口的invoke方法在org.apache.catalina.core.ContainerBase类的实现
public void invoke(Request request, Response response) throws IOException, ServletException { pipeline.invoke(request, response); }
pipeline是容器内部的Pipeline接口的实例。
现在,pipeline必须确认所有的valve被添加,basic valve必须被调用一次。pipeline通过创建一个ValveContext接口的实例来完成valve的添加确认。ValveContext是作为一个pipeline的内部类实现的,所以ValveContext可以访问pipeline的所有成员。ValveContext接口的最重要的方法是invokeNext方法:
public void invokeNext(Request request, Response response) throws IOException, ServletException
创建了一个ValveContext实例后,pipeline调用ValveContext的invokeNext方法。ValveContext将首先调用pipeline中的第一个valve,然后第一个valve在它完成了任务前将调用下一个valve。ValveContext把它自己传递给每一个valve,所以valve可以调用ValveContext的invokeNext方法。
public void invoke(Request request, Response response, ValveContext ValveContext) throws IOException, ServletException
一个valve的invoke方法的实现:
public void invoke(Request request, Response response, ValveContext valveContext) throws IOException, ServletException { // Pass the request and response on to the next valve in our pipeline valveContext.invokeNext(request, response); // now perform what this valve is supposed to do ... }
org.apache.catalina.core.StandardPipeline类是在所有容器的Pipeline的实现。在Tomcat 4中,这个类有一个叫做StandardPipelineValveContext的实现了ValveContext接口的内部类。
Listing 5.1: The StandardPipelineValveContext class in Tomcat 4 protected class StandardPipelineValveContext implements ValveContext { protected int stage = 0; public String getInfo() { return info; } public void invokeNext(Request request, Response response) throws IOException, ServletException { int subscript = stage; stage = stage + 1; // Invoke the requested Valve for the current request thread if (subscript < valves.length) { valves[subscript].invoke(request, response, this); } else if ((subscript == valves.length) && (basic != null)) { basic.invoke(request, response, this); } else { throw new ServletException (sm.getString("standardPipeline.noValve")); } } }
invokeNext方法使用下标(subscript)和状态(stage)来明确指出哪一个valve被调用过。当在pipeline的invoke方法第一个valve被调用时,下标值是0,状态值是1。因此,第一个valve(数组下标是0)被调用。在pipeline中的第一个valve接收ValveContext实例和调用它的invokeNext方法。这时,下标值是1,当然第二个valve被调用,以此类推。
当最后一个valve的invokeNext方法被调用时,下标值是等于valve的数量。最后,basic valve被调用。
Tomcat 5从StandardPipeline中移除了StandardPipelineValveContext类,而依靠org.apache.catalina.core.StandardValveContext。
Listing 5.2: The StandardValveContext class in Tomcat 5 package org.apache.catalina.core; import java.io.IOException; import javax.servlet.ServletException; import org.apache.catalina.Request; import org.apache.catalina.Response; import org.apache.catalina.Valve; import org.apache.catalina.ValveContext; import org.apache.catalina.util.StringManager; public final class StandardValveContext implements ValveContext { protected static StringManager sm = StringManager.getManager(Constants.Package); protected String info = "org.apache.catalina.core.StandardValveContext/1.0"; protected int stage = 0; protected Valve basic = null; protected Valve valves[] = null; public String getInfo() { return info; } public final void invokeNext(Request request, Response response) throws IOException, ServletException { int subscript = stage; stage = stage + 1; // Invoke the requested Valve for the current request thread if (subscript < valves.length) { valves[subscript].invoke(request, response, this); } else if ((subscript == valves.length) && (basic != null)) { basic.invoke(request, response, this); } else { throw new ServletException (sm.getString("standardPipeline.noValve")); } } void set(Valve basic, Valve valves[]) { stage = 0; this.basic = basic; this.valves = valves; } }
你可以看见Tomcat 4中的StandardPipelineValveContext类和Tomcat 5 中的StandardValveContext类相似。
下面们将要详细讨论Pipeline, Valve和 ValveContext接口:
评论
2 楼
dicmo
2010-12-10
amwiacel 写道
一个容器可以用
org.apache.catalina.Container接口表示。这里有四种类型的容器:Engine, Host, Context 和Wrapper。 这种直译不是很好,其实这种分法是一种抽象模型,得从设计模式上去理解其意思。
org.apache.catalina.Container接口表示。这里有四种类型的容器:Engine, Host, Context 和Wrapper。 这种直译不是很好,其实这种分法是一种抽象模型,得从设计模式上去理解其意思。
谢谢指正。这个措词是不恰当。抽象层面的东西。
1 楼
amwiacel
2010-12-10
一个容器可以用
org.apache.catalina.Container接口表示。这里有四种类型的容器:Engine, Host, Context 和Wrapper。 这种直译不是很好,其实这种分法是一种抽象模型,得从设计模式上去理解其意思。
org.apache.catalina.Container接口表示。这里有四种类型的容器:Engine, Host, Context 和Wrapper。 这种直译不是很好,其实这种分法是一种抽象模型,得从设计模式上去理解其意思。
发表评论
-
MyEclipse插件安装
2012-03-22 10:05 4321:先把plugin的jar文件复制到一个文件夹下 如:C:/ ... -
Hibernate框架使用技术简述
2011-03-24 10:14 1131(1)持久化对象的操 ... -
Coder 爱翻译 How Tomcat Works 第九章 第二部分
2011-01-24 15:20 1171The ManagerBase Class ManagerB ... -
Coder 爱翻译 How Tomcat Works 第九章 第一部分
2010-12-16 20:40 1263Chapter 9: Session Management ... -
Coder 爱翻译 How Tomcat Works 第八章 第二部分
2010-12-12 18:31 1516The Loader Interface 在web应 ... -
Coder 爱翻译 How Tomcat Works 第八章 第一部分
2010-12-06 11:14 1097Chapter 8: Loader 在前几章 ... -
Coder 爱翻译 How Tomcat Works 第七章
2010-12-05 16:29 1189Chapter 7: Logger 日志是一 ... -
Coder 爱翻译 How Tomcat Works 第六章
2010-12-04 22:09 1167Chapter 6: Lifecycle Catalina是 ... -
Coder 爱翻译 How Tomcat Works 第五章 第三部分
2010-12-03 13:31 1152The Context Application 这章的第一个 ... -
Coder 爱翻译 How Tomcat Works 第五章 第二部分
2010-12-03 12:33 3108The Pipeline Interface 我们提到的Pi ... -
Coder 爱翻译 How Tomcat Works 第四章 第二部分
2010-11-27 15:07 1057Request Objects 在默认的连接器中org.ap ... -
Coder 爱翻译 How Tomcat Works 第四章 第一部分
2010-11-25 16:38 946Chapter 4: Tomcat Default Conne ... -
PreparedStatement字符串拼接
2010-11-18 17:21 1404这在里求JDBC中PreparedStatement的实现,我 ... -
HelloWorld的javap -verbose HelloWorld 字节码初探
2010-11-17 12:20 3124基本的HelloWorld类: public class ... -
How Tomcat Works 简单目录
2010-11-16 14:51 1444第1章:通过一个简单的HTTP服务器开始这本书的内容。构建一个 ... -
Coder 爱翻译 How Tomcat Works 第三章 第三部分
2010-11-15 19:24 1031Parsing Headers 一个HttpHeader类 ... -
Coder 爱翻译 How Tomcat Works 第三章 第二部分
2010-11-14 20:13 1092The Connector(连接器) HttpConnect ... -
回应某面试题
2010-11-10 21:31 1322上午看了一JAVAEYE的一个上机题:http://www.i ... -
quartz简单应用
2010-11-10 11:49 1000Job类:实现Job接口,接口中有一个execute()方法, ... -
coder 爱翻译 How Tomcat Works 第三章 第一部分
2010-11-05 11:41 1132第三章: Connector 在正式 ...
相关推荐
适合读者 1.jsp/servlet 开发人员,想了解 tomcat 内部机制的 coder; 2.想加入 tomcat 开发团队的 coder; 3.web 开发人员,但对软件开发很有兴趣的 coder; 4.想要对 tomcat 进行定制的 coder。
Bad Programming Practices 101 Become a Better Coder by Learning How (Not) to Program 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书
PHPCoder是一款专为PHP开发者设计的高效代码编辑器,旨在提供一个轻量级且功能丰富的开发平台。这款软件以其便捷性、易用性和强大的功能深受程序员喜爱。在本篇文章中,我们将深入探讨PHPCoder的各项特性、安装过程...
6. 插件扩展:MediaCoder有一个开放的插件架构,用户可以通过安装第三方插件来增加新的编码解码器、滤镜和其他功能,扩展其应用范围。 7. 用户友好:MediaCoder的界面简洁直观,即便是对编码不熟悉的用户也能快速...
mediacoder 5685专业版,无普通版的限制
综上所述,Simulink HDL Coder 作为一款先进的工具,极大地简化了从算法设计到 FPGA 实现的整个过程,是现代电子设计自动化领域不可或缺的一部分。通过掌握其使用方法和技术要点,工程师们能够更高效地完成复杂的 ...
Mediacoder是一款强大的多媒体编码工具,专为音频和视频转换而设计,支持多种格式,如MP4、AVI、MKV等。本教程将深入讲解如何利用Mediacoder进行视频压制,优化视频质量,同时合理权衡码率与视频大小的关系。 **1. ...
Embedded Coder用于产生嵌入式处理器、目标快速原型板和大规模生产中使用的微处理器的可读的、紧凑的、快速的C和C++代码。Embedded Coder支持附加的MATLAB Coder™和Simulink Coder™配置选项,以及对生成代码的功能...
Martin, "The Clean Coder: A Code of Conduct for Professional Programmers" Prentice Hall | 2011 | ISBN: 0137081073 | 256 pages | PDF | 6 MB Programmers who endure and succeed amidst swirling ...
虽然CoolCoder能够自动化大部分工作,但开发者依然可以自定义模板,对生成的代码进行微调,以满足特定项目的需求。这种灵活性确保了生成的代码既高效又符合项目风格。 6. **提高开发效率**: 使用CoolCoder,...
MediaCoder是一款功能强大的多媒体转换工具,它支持广泛的音频和视频编码格式,使用户能够轻松地在不同设备之间转换媒体文件。这款软件适用于个人用户、专业音频和视频制作人员,以及那些希望在各种设备上享受多媒体...
PHPCoder用于快速开发和调试PHP应用程序,它很容易扩展和定制,完全能够符合开发者的个性要求.PHPCoder是一个非常实用的,功能强大的编程环境,而且它是免费的!
### MATLAB Coder 基本函数教程 #### MATLAB Coder 概述 MATLAB Coder 是一款能够将 MATLAB 代码转换成独立的 C 或 C++ 代码的强大工具。这一过程对于那些希望在非 MATLAB 环境下部署 MATLAB 代码的应用开发者来说...
### HDL-Coder详细教程知识点概述 #### 一、生成HDL代码前的准备工作 在开始从Simulink模型生成HDL代码之前,需要完成一系列的准备工作,确保模型能够顺利生成高质量的代码。 ##### 1.1 使用`hdlsetup`进行模型...
MediaCoder行业版一款针对VOD及KTV视频点播行业开发的,用于转换和处理带有多音轨内容的视频节目的软件。它具备业界领先的视频编码引擎,在高性能转码的同时保持高画质,并通过丰富的视频滤镜增强画面视觉效果。作为...
MediaCoder使用说明文档, mediaCoder usermanual,
Matlab Coder是Mathworks公司推出的一款用于将Matlab代码转换成高效C代码的工具。从2004年开始,Matlab陆续在Simulink中添加了Embeded Matlab Function模块,2007年在Real-Time Workshop中引入了emlc函数(现在的...
texasinstrumentsc2000.mlpkginstall 支持TI的C2000系列工具包,要求MATLAB R2017a及其以上版本。 安装方法:打开matlab,调整路径到mlpkginstall文件所在目录;在current folder窗口里双击mlpkginstall文件即可开始...
接下来,我们讨论"magicalcoder文件去域名"的第二个方面——软件授权限制的解除。通常,商业软件会设定一定的授权机制,包括使用期限、设备数量或特定的使用环境(如特定域名)。这些限制是为了保护知识产权,防止...