tomcat 将一个包中所有类使用的错误信息存储在 properties 文件中,每个包有一个  properties 文件。每个 properties 文件都是用 org.apache.catalina.util.StringManager 类的一个实例来处理的,通一个包下的许多类使用同一个 StringManager 实例(单例模式)

例如,要想从 ex.03.pyrmont.connector.http 包下的类中使用 StringManager ,需要将包名字符串作为参数传到 StringManager 类的 getManager() 方法中:

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

在 ex.03.pyrmont.connector.http 包下,可以找到三个 properties 文件,LocalString.properties, LocalString_es.properties 和 LocalString_ja.properties 。StringManager 实例会根据运行该程序的服务器的语言环境来选择使用哪个文件。若打开 LocalString.properties 文件,第一个非注释行的内容如下:

httpConnector.alreadyInitialized = HTTP connector has already been initialized

调用 StringManager 类的 getString() 方法,该方法传入错误码 “httpConnector.alreadyInitialized”,得到错误信息“HTTP connector has already been initialized”。

等待 HTTP 请求的工作由 HttpConnector 实例完成。

创建 Request 和 Response 对象的工作由 HttpProcessor 实例完成。

javax.servlet.http.HttpServletRequest

public interface HttpServletRequest extends ServletRequest

上图中的 HttpRequest 类实现 javax.servlet.http.HttpServletRequest 接口, HttpRequest  对象会被转型为 HttpServletRequest  对象,然后传递给被调用的 servlet 实例的 service() 方法。因此,必须正确地设置每个 HttpRequest 实例地成员变量供 servlet 实例使用。需要设置地值包括:URI、查询字符串、参数、Cookie 和其它一些请求头信息。若是来凝结其仅仅解析会被 servlet 实例用到的值会节省很多 CPU 周期。在这些参数被 servlet 实例真正调用前,tomcat 默认连接器包括本章中的连接器是不会解析他们的。

SocketInputStream 实例时 java.io.InputStream 实例的包装类,提供了两个重要方法:

    • readRequestLine():返回一个 HTTP 请求第一行的内容,包含了 请求方法、URI、HTTP 版本信息。返回值是一个 HttpRequestLine 实例。
    • readHeader():每次调用都会返回一个 名/值 对,所以应该重复调用此方法,知道读取了所有请求头信息。返回值是一个 HttpHeader 对象。

套接字的输入流中处理字节流是指读取从第一个字节到最后一个字节的内容,因此 readRequestLine() 方法必须在 readHeader() 之前调用。

HttpConnector 类实现了 java.lang.Runable, 当启动应用时,创建 HttpConnector 的一个实例并执行它的 run() 方法

run() 方法包含一个 while 循环,在循环中执行如下三个操作:

    • 等待 HTTP 请求
    • 为每个请求创建一个 HttpProcessor 实例
    • 调用 HttpProcessor 对象的 process(Socket socket)方法

HttpProcessor 类的 process() 方法接收来自传入的 HTTP 请求的套接字。对于每个传入的 HTTP 请求,他要完成 4 个操作:

    • 创建一个 HttpRequest 对象
    • 创建一个 HttpResponse 对象
    • 解析 HTTP 请求的第 1 行内容和请求头信息,填充 HttpRequest 对象
    • 将 HttpRequest 对象和 HttpResponse 对象传递给 servletProcessor 或 StaticResourceProcessor 的 process 方法。servletProcessor 类会调用请求的 servlet 实例的 service 方法,StaticResourceProcessor 类会将请求的静态资源发送给客户端。
public void process (Socket socket) {
SocketInputStream input = null;
OutputStream output = null; try { input = new SocketInputStream(socket.getInputStream, 2048);
output = socket.getOutputStream(); // create HttpRequest object and parse
request = new HttpRequest(input); //create HttpResponse object
response = new HttpResponse(output);
response.setRequst(request); response.setHeader("Server", "Pyrmont Servlet Container"); parseRequest(input, output);
parseHeader(input); //check if this is a request for a servlet or a static resource
if (request.getRequestURI().startsWith("/servlet/")) {
ServletProcessor processor = new ServletProcessor();
processor.process(request, response);
}
else {
StaticResourceProcessor processor = new StaticResoureProcessor();
processor.process(request, response);
} //Close the socket
socket.close();
//no shutdown for this application
}
catch (Exception e) {
e.printStackTracec();
}
}

解析 HTTP 请求

1、读取套接字的输入流

之所以使用 SocketInputStream 类就是为了调用其 readRequestLine() 方法和 readHeader() 方法。

2、解析请求行

GET /myApp/chat/session/state?custId=1032785&pwd=1234 HTTP/1.1

URI 是 /myApp/chat/session/state,问号后面的部分就是查询字符串,查询字符串可以包含 0 个或多个请求参数。先调用 SocketInputStream 类的 readRequestLine() 方法。

3、解析请求头

while 循环不断调用 SocketInputStream 类的 readHeader() 方法。

4、解析  Cookie

Cookie: userName=budi;password=pwd;

Cookie 是由浏览器作为 HTTP 请求头的一部分发送的。这样请求头的名称是 "cookie"。上面这个 Cookie 请求头的例子中包含两个 Cookie : userName 和 password。解析后返回 javax.servlet.http.Cookie 类型的一个数组,数组中的元素个数与 Cookie 请求头中 名/值 对的数目相同。

5、获取参数

参数可以出现在查询字符串或请求体中。若 GET 请求 servlet,全在查询字符串中。若 POST ,则请求体中也可能会有参数。放在特殊的 HashMap 类:org.apache.catalina.util.ParameterMap 。其中有一个名为 locked 的布尔变量。只有当 locked 值为 false 时,才可以对 ParameterMap 对象中的 名/值对 进行添加、更新或删除操作。否则会抛出 IllegalStateException。但是可以在任何时候读取该值。用 org.apache.catalina.util.RequestUtil 的 parseParameters 方法完成解析。最后返回 ParameterMap 时,要将结果的 locked 设为 true 锁住,使其内容保持一致,再赋值。

在 servlet 中,可以使用 java.io.PrintWriter 对象向输出流中写 字符。可以使用任意编码格式。当在向浏览器中发送字符时,实际上都是字节流

tomcat 2 - 默认连接器精简版的更多相关文章

  1. 攻城狮在路上(伍)How tomcat works(四)Tomcat的默认连接器

     在第4章中将通过剖析Tomcat4的默认连接器的代码,讨论需要什么来创建一个真实的Tomcat连接器.     注意:本章中提及的“默认连接器”是指Tomcat4的默认连接器.即使默认的连机器已经被 ...

  2. how tomcat works 读书笔记四 tomcat的默认连接器

    事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...

  3. Tomcat剖析(四):Tomcat默认连接器(2)

    Tomcat剖析(四):Tomcat默认连接器(2) 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三): ...

  4. Tomcat剖析(四):Tomcat默认连接器(1)

    Tomcat剖析(四):Tomcat默认连接器(1) 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三): ...

  5. tomcat源码阅读之默认连接器

    默认连接器 一.UML图: 1.所有的连接器都要实现Connector接口,必须创建Request对象和Response对象,httpConnector作为默认连接器,肯定也是要实现Connector ...

  6. 一般的linux系统默认安装的vim是精简版

    一般的linux系统默认安装的vim是精简版(vim-tiny),所以不能配置语法检查等属性或获取在线帮助.需要安装vim-x:x.x.x,vim-common,vim-runtime. :synta ...

  7. Tomcat 七 HTTP 连接器

    摘要 本文尝试翻译Tomcat官方文档Apache Tomcat 7连接器,不足之处敬请指正.该文先介绍了Tomcat7 HTTP连接器的属性,包括:公共属性.标准实现.Java TCP套接字属性.B ...

  8. Linux上oracle精简版客户端快速部署

    RHEL6 + Oracle 11g客户端快速部署 需求:只是用到客户端的sqlplus, sqlldr功能. 方案:用精简版实现客户端的快速部署 1.上传oracle精简版客户端到服务器/tmp目录 ...

  9. TeamViewer12.0.71503(远程控制软件)精简版 单文件企业版介绍

    TeamViewer 是一款能在任何防火墙和 NAT 代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamViewer 即可 ...

  10. TeamViewer12.0.71503(远程控制软件)精简版单文件企业版介绍

    TeamViewer 是一款能在任何防火墙和 NAT 代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamViewer 即可 ...

随机推荐

  1. LINQ中AsQueryable()和AsEnumerable()区别

    在进行EF数据查询时,AsEnumerable()会直接生成将LINQ语句生成sql脚本并到数据库中执行,并将结果加载到内存中,后续操作都是操作内存中的对象: AsQueryable()则可继续进行L ...

  2. git常规操作

    git拉代码 使用git clone命令从仓库下载代码,代码下载到了本地:git clone 链接 如果仓库代码又了更新,这时可以使用git pull命令将更新下载到本地 在对本地代码就行修改后,可以 ...

  3. oracle 行转列,动态年份,月份列。已解决!

    -----------------存储过程包体----------- procedure GetComparativeAnalysisTB(p_StartTime varchar2, ----开始时间 ...

  4. ts-基础

    1. 定义变量// 将b赋值为 hello,只能是 hello或者 wowrldlet b : "hello" | "world" // 设置变量c只能为num ...

  5. 防止IO持续信号

    List<int> list = new List<int>() { 1,11, 2,3, 4,5, 6,22, 7, 8,9,10 };//产品:双数为ng 单数为ok bo ...

  6. Java集合-练习巩固

    练习一 public class H1_Test { public static void main(String[] args) { H1_News h1News = new H1_News(&qu ...

  7. Create React App 安装时出现的错误解决方法

    安装很简单 创建一个文件夹  xxx 第一步:npx create-react-app my-app 第二部:cd my-app 第三部:npm start 安装时出现的错误  一 解决方案 一: 全 ...

  8. 嵌在Android app的html 拨打不了电话,发送不了短信

    html嵌在app里面的 <a href="tel:xxx"></a> <a href="sms:phoneNmber?body=1111& ...

  9. 修改python下载镜像源

    找到pip.ini(可能在"C:\Users\Administrator\AppData\Roaming\pip\pip.ini")→记事本打开→添加相应源 如果没有找到,在C:\ ...

  10. IaaS--云硬盘(何恺铎《深入浅出云计算》笔记整理)

    [概念] 云硬盘,又叫做"云盘"或者"云磁盘",就是云虚拟机上可以挂载和使用的硬盘.这里,它既包含了用于承载操作系统的系统盘,也包括了承载数据的数据盘.云厂商对 ...