设为首页 收藏本站
查看: 325|回复: 0

[经验分享] coder 爱翻译 How Tomcat Works 第三章 第一部分

[复制链接]

尚未签到

发表于 2017-2-5 10:04:33 | 显示全部楼层 |阅读模式
第三章: 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 ();
}
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-337678-1-1.html 上篇帖子: 项目从jetty服务器换tomcat乱码 下篇帖子: 《How Tomcat Works》翻译(9) 之 会话管理续集
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表