`
dicmo
  • 浏览: 68347 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

coder 爱翻译 How Tomcat Works 第三章 第一部分

    博客分类:
  • j2ee
阅读更多
第三章: Connector

在正式开始这个应用之前,我们先以org.apache.catalina.util包下的StringManager作为开始。这个类用来处理在应用程序中和Cacalina本身错误信息的国际化。

The StringManager Class

一个像Tomcat这样大的应用需要很小心地处理错误信息。Tomcat的错误信息对系统管理员和servlet程序员都是非常有用的。例如:Tomcat的logs错误信息可以让系统管理员很精确地定位异常的发生。对servlet程序员,Tomcat发送javax.servlet.ServletException抛出的特定的错误信息,让程序员知道他的servlet出了什么问题。

Tomcat的解决办法是在properties文件中存储错误信息,所以编辑它们就很容易。但是在Tomcat中有几百个类,存储所有的被使用类的错误信息在一个大的properties文件中很容易为维护带来麻烦(a maintenance nightmare)。为了避免这种情况,Tomcat为每一个包分配一个properties文件。例如:在org.apache.catalina.connector包下的properties文件包含所有在这包下类可能抛出的的错误信息。每个properties文件由org.apache.catalina.util.StringManager类的实例处理。当Tomcat一运行,就会有许多的StringMnager类的实例生成。每一个包对应一个StringManager实例来读取一个properties文件具体内容。由于Tomcat的广泛应用,提供多种语言的错误信息就显得很有必要了。现在支持有三种语言。英语版本的错误信息是叫做LocalStrings.properties的文件。另外两种是西班牙语和日语,分别为:LocalString_es和LocalString_js.properties文件。

当一个包中的类需要在该包的properties文件中查询一个错误信息时,它首先要获得一个StringManager实例。但是,同一个包下面的许多类可能需要一个StringManager。浪费资源来为每一个需要的错误信息的对象来创建一个StringManager实例。
如果你熟悉设计模式,你可以很正确地想到StringManager是一个单例类。唯一的构造函数是private修饰。所以你不能使用new关键字来类的外面实例化它。你可以通过传递一个包名,调用public static getManager方法来获得一个实例。每一个实例以它的包名为key存储在Hashtable中。
private static Hashtable managers = new Hashtable(); 
public synchronized static StringManager getManager(String packageName) { 
StringManager mgr = (StringManager)managers.get(packageName); 
if (mgr == null) { 
mgr = new StringManager(packageName); 
managers.put(packageName, mgr);
}
return mgr; 
}


例如:使用ex03.pyrmont.connector.http包下的StringManager:

StringManager sm = StringManager.getManager("ex03.pyrmont.connector.http");

在ex03.pyrmont.connector.http包下,你可以找到3个properties文件:
LocalStrings.properties, LocalStrings_es.properties 和LocalStrings_ja.properties。这些文件会被StringManager实例使用。使用哪一个文件取决于服务器运行的应用的区域设置。如果你打开LocalStrings.properties文件,第一行没有注释的代码:

httpConnector.alreadyInitialized=HTTP connector has already been initialized

为了获取错误信息,可以使用StringManager类的getString方法。这个方法需要传递一个错误代号码(error code)。

public String getString(String key)

把httpConnector.alreadyInitialized作为参数传递给getString方法返回:
HTTP connector has already been initialized。

The Application

开始这一部分,我们把应用分成模块。连接器模块所包含的类可以分组成为5个类别:

 The connector and its supporting class (HttpConnector and HttpProcessor). 连接器和它支持的类
 The class representing HTTP requests (HttpRequest) and its supporting classes.代表HTTP请求和其支持的类.
 The class representing HTTP responses (HttpResponse) and its supporting classes.代表HTTP响应及其支持的类
 Facade classes (HttpRequestFacade and HttpResponseFacade). Facade类(门面类)
 The Constant class.

核心模块包含2个类:ServletProcessor和StaticResourceProcessor

第二章的HttpServer类是负责等待HTTP请求和生成request和response对象。在这章,等待HTTP请求的任务给了HttpConnector实例,而创建request和response对象的任务分配给了HttpProcessor实例。

在这章,HTTP请求对象就是实现了javax.servlet.http.HttpServletRequest接口的HttpRequest类。一个HttpRequest对象会被转型为一个HttpServletRequest实例,然后传递给servlet的service方法调用。此外,每一个HttpRequest实例必须填充它自己的字段(fields)以便servlet可以使用它们。HttpRequest对象中的包括URI,查询字符串,参数,cookies和其他头部信息等需要被赋值。因为连接器不知道哪个值需要被servlet调用,所以连接器必须解析所有HTTP请求获取的值。但是,解析一个HTTP请求包括字符串和其他操作是有很大开销的,连接器可以保存许多CPU周期以便只解析那些servlet真正只需要的值。例如:如果servlet不需要任何请求参数(不调用getParameter等javax.servlet.http.HttpServletRequest方法),这时连接器就不需要解析这些从查询字符串或者HTTP请求体的参数。Tomcat的默认连接器更加高效:在servlet到了真的需要的时候才去执行参数解析。

Tomcat默认的连接器和我们这个连接器使用SocketInputStream类来读取从socket的InputStream字节流。SocketInputStream的实例是包装了socket的getInputStream方法返回的java.io.InputStream实例。SocketInputStream类提供2个重要的方法:readRequestLine和readHeader。ReadRequestLine返回一个HTTP请求的第一行内容,例如:URI,方法(POST等),HTTP版本。因为处理来自socket的输入流的字节流意味着读取第一个字节到最后一个字节。(但是不会向回读取 backwards),所以readRequestLine必须只被调用一次且必须在调用readHeader方法之后。每次调用readHeader方法是用来获取一个头部信息的name/value对。它会被重复调用,直到读完所有的头信息。readRequestLine的返回值是一个HttpRequestLine实例,readHeader的返回值是一个HttpHeader对象。下面我们讨论HttpRequestLine和HttpHeader类。

HttpProcessor对象创建HttpRequest实例,然后必须填充他们的字段。HttpProcessor类,使用parse方法,解析一个HTTP请求的请求行和头部信息。这些被解析的结果会填充在HttpProcessor对象的字段中。但是,这parse方法不会解析在请求体或查询字符串的参数。这个任务交给了HttpRequest对象自己解决。只有servlet需要一个参数的时候,这个参数它才会在查询字符串或请求体中解析。

我们一下面几个小部分开始详细介绍这个应用:

 Starting the Application 开始这个应用程序
 The Connector  连接器
 Creating an HttpRequest Object 创建一个HttpRequest对象
 Creating an HttpResponse Object 创建一个HttpResponse对象
 Static resource processor and servlet processor 静态资源处理器和servlet处理器
 Running the Application 运行这个应用程序

Starting the Application

从Bootstrap类开始: bootstrap(自举或引导程序)
Listing 3.1: The Bootstrap class 

package ex03.pyrmont.startup; 
import ex03.pyrmont.connector.http.HttpConnector; 
public final class Bootstrap { 
public static void main(String[] args) { 
HttpConnector connector = new HttpConnector(); connector.start();
} 
}

Bootstrap类的主函数实例化了HttpConnector类和调用它的start方法。下面是HttpConnector:
Listing 3.2: The HttpConnector class's start method 

package ex03.pyrmont.connector.http; 
import java.io.IOException; 
import java.net.InetAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
public class HttpConnector implements Runnable { 
boolean stopped; 
private String scheme = "http"; 
public String getScheme() { 
return scheme;
} 
public void run() { 
ServerSocket serverSocket = null; 
int port = 8080;
try { 
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException e) { 
e.printStackTrace(); 
System.exit(1); 
} 
while (!stopped) {
// Accept the next incoming connection from the server socket 
Socket socket = null; 
try { 
socket = serverSocket.accept(); 
} catch (Exception e) { 
continue; 
} 
// Hand this socket off to an HttpProcessor 
HttpProcessor processor = new HttpProcessor(this);
 			processor.process(socket); 
}
} 
public void start() { 
Thread thread = new Thread(this); 
thread.start ();
} 
}

0
0
分享到:
评论

相关推荐

    tomcat原理解析书(how-tomcat-works)中文版

    适合读者 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) epub

    Bad Programming Practices 101 Become a Better Coder by Learning How (Not) to Program 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书

    phpcoder.rar

    - **插件扩展**:PHPCoder支持第三方插件,可以通过社区下载安装增强功能。 - **代码格式化**:使用“编辑”>“格式化代码”对代码进行整理,保持良好的编码风格。 - **搜索与替换**:利用查找和替换功能,可以在...

    matlab Embedded Coder Getting Started Guide.pdf

    Embedded Coder用于产生嵌入式处理器、目标快速原型板和大规模生产中使用的微处理器的可读的、紧凑的、快速的C和C++代码。...你可以将第三方开发环境引入到工程构建过程中,以产生用于在嵌入式系统上应用的可执行文件。

    MediaCoder答题器

    6. 插件扩展:MediaCoder有一个开放的插件架构,用户可以通过安装第三方插件来增加新的编码解码器、滤镜和其他功能,扩展其应用范围。 7. 用户友好:MediaCoder的界面简洁直观,即便是对编码不熟悉的用户也能快速...

    一维码第三方CODER

    总之,一维码第三方CODER服务是IT行业中不可或缺的一部分,它们为企业和开发者提供了强大而灵活的工具,用于管理和追踪物品信息。了解并熟练运用这类服务,可以极大地提升工作效率和数据管理的准确性。

    mediacoder专业版

    mediacoder 5685专业版,无普通版的限制

    simulink hdl coder 用户手册pdf

    综上所述,Simulink HDL Coder 作为一款先进的工具,极大地简化了从算法设计到 FPGA 实现的整个过程,是现代电子设计自动化领域不可或缺的一部分。通过掌握其使用方法和技术要点,工程师们能够更高效地完成复杂的 ...

    Mediacoder基础教程

    Mediacoder是一款强大的多媒体编码工具,专为音频和视频转换而设计,支持多种格式,如MP4、AVI、MKV等。本教程将深入讲解如何利用Mediacoder进行视频压制,优化视频质量,同时合理权衡码率与视频大小的关系。 **1. ...

    The Clean 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 类生成工具

    虽然CoolCoder能够自动化大部分工作,但开发者依然可以自定义模板,对生成的代码进行微调,以满足特定项目的需求。这种灵活性确保了生成的代码既高效又符合项目风格。 6. **提高开发效率**: 使用CoolCoder,...

    matlab coder基本函数教程

    这在某些情况下非常有用,特别是当原始 M 文件包含敏感信息且不希望直接暴露给第三方时。 ```matlab coder.allowpcode('plain') ``` #### 外部函数调用 - **coder.ceval 和 coder.extrinsic**:这两个函数用于...

    MediaCoder

    MediaCoder是一款功能强大的多媒体转换工具,它支持广泛的音频和视频编码格式,使用户能够轻松地在不同设备之间转换媒体文件。这款软件适用于个人用户、专业音频和视频制作人员,以及那些希望在各种设备上享受多媒体...

    php coder编辑器

    PHPCoder用于快速开发和调试PHP应用程序,它很容易扩展和定制,完全能够符合开发者的个性要求.PHPCoder是一个非常实用的,功能强大的编程环境,而且它是免费的!

    HDL-Coder详细教程

    ### HDL-Coder详细教程知识点概述 #### 一、生成HDL代码前的准备工作 在开始从Simulink模型生成HDL代码之前,需要完成一系列的准备工作,确保模型能够顺利生成高质量的代码。 ##### 1.1 使用`hdlsetup`进行模型...

    MediaCoder.5755专业破解版

    MediaCoder行业版一款针对VOD及KTV视频点播行业开发的,用于转换和处理带有多音轨内容的视频节目的软件。它具备业界领先的视频编码引擎,在高性能转码的同时保持高画质,并通过丰富的视频滤镜增强画面视觉效果。作为...

    MediaCoder使用说明文档

    MediaCoder使用说明文档, mediaCoder usermanual,

    MatlabCoder使用-Matlab Coder的基本使用.pdf

    Matlab Coder是Mathworks公司推出的一款用于将Matlab代码转换成高效C代码的工具。从2004年开始,Matlab陆续在Simulink中添加了Embeded Matlab Function模块,2007年在Real-Time Workshop中引入了emlc函数(现在的...

    Embedded Coder.rar

    texasinstrumentsc2000.mlpkginstall 支持TI的C2000系列工具包,要求MATLAB R2017a及其以上版本。 安装方法:打开matlab,调整路径到mlpkginstall文件所在目录;在current folder窗口里双击mlpkginstall文件即可开始...

Global site tag (gtag.js) - Google Analytics