【How Tomcat Works】第一章——一个简易的java web服务实现(上)
来源:互联网 发布:淘宝宝贝无线链接地址 编辑:程序博客网 时间:2024/05/22 07:59
以HTTP知识深入讲解作为本章的开头,甚至是实质意义上本书的开头,鲜有其他Tomcat技术书能够做到,因为这样做非常“冒险的”,冒险的原因在于既没有立马对Tomcat庖丁解牛式的讲解,亦不能让我们看完之后快速上手开发Web应用。如果以前放在我的面前,我也是几乎不会碰的。不过面对这样一个“冒险”开头又是英文版的书,我能痴之入迷完全得归功于另一本非常优秀的Tomcat相关的书——《Tomcat与Java Web开发技术详解》。一本中文书,作者是孙卫琴,一个重质不重量的技术作者。这本书的前几章把我带到了一个不同的世界,犹如儒勒·凡尔纳将我带到了令人惊叹的海底两万里。看完这边书后,有一次在百度知道上回答了一个网友的提问,得到了一个受惊若宠的好评。这个好评一方面让我很有成就感,而另一方面“惊”的就是,在内心深处我明白并没有真正的到达海底的两万里,孙卫琴的书只能帮我安全潜入水,继续修行还得靠个人。
开篇
本章比较系统的讲解了Java web 服务器的运作详情(这种系统的讲解除了Java层面,如果有计算机网络方面的知识会更为有共鸣感)。Web服务器又可称作为超文本协议(HTTP)服务器,它用到了HTTP协议和客户端交互,客户端包括但不限于我们熟悉的web浏览器。对于基于Java实现的web服务程序,就不得不提以下两个类:java.net.Socket和java.net.ServerSocket。所以自然而然,本章将会以对HTTP协议和这两个类的探讨为开头,继而会讲解如何实现一个简单的web服务程序。
HTTP家族的生活
本章的HTTP知识内容包括HTTP协议本身、HTTP请求、HTTP响应。当然HTTP家族成员当然不限于上述,比如大名鼎鼎的网页设计、CSS、TCP/IP等等,都是它的内亲外戚。
HTTP协议一瞥
在互联网中,web服务器程序和浏览器程序交换需要发送和接受数据,但由于互联网异构属性,传输的数据要受到一个格式的要求,以便屏蔽掉这种存在的异构,否则就会像两个哑巴对话一样,各说各的语言,彼此觉得还听懂了对方。为此,HTTP协议应运而生,这是一种请求/响应类型协议。所谓请求,是客户端的请求,就是客户端请求一个文件(显然,现在用“资源”一词更好);而所谓响应,是服务器的响应,也就是根据上述请求做出的回应。HTTP是基于可靠的TCP连接——默认TCP端口为80。HTTP经历了从HTTP/0.9到现在的HTTP/1.0的发展历程,详情可参考W3C发布的标准说明文档。
上述讲到,请求是客户端的请求,响应是服务器的响应,意思就是在HTTP中表现为由客户端建立连接发起交互,并发送请求,而服务器端是绝不可能主动和客户端通信或者是回拨连接(莫非FTP或者其他协议不是这样的??)。而无论服务端还是客户端都有权主动终端连接。比如你下载一个文件,如果你点击了网页的取消按钮,将会关闭与web服务器的HTTP连接。
HTTP Request的内心独白
Request和Response是我们在jsp或者是servlet编程接触最多的一个东东,通常的标题是作为jsp/servlet一个重要的内置对象,然后跟着一大堆Request的方法讲解。下面要真正走进Request的内心世界。本内容还可参考孙卫琴的《Tomcat与Java Web开发技术详解》一书。
HTTP请求通常由三部分组成
1、请求方法——统一资源定位符(URI)——协议/版本
2、请求头
3、请求实体
其中请求实体以一空行区别于请求头,以下面的一个请求为例,对Request进行详谈。
POST /examples/default.jsp HTTP/1.1Accept: text/plain; text/htmlAccept-Language: en-gbConnection: Keep-AliveHost: localhostUser-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)Content-Length: 33Content-Type: application/x-www-form-urlencodedAccept-Encoding: gzip, deflate lastName=Franks&firstName=Michael
请求头包含了浏览器语言环境、请求实体长度等重要信息,并以键值对的形似出现。(请求头是我们编程时的盲区,基本接触不多)。
lastName=Franks&firstName=Michael对应请求实体。实际中,一个请求实体远比例子给出的长。
HTTP Response的独自等待
作为Request的孪生兄弟,Response长得也和它差不多,由三部分组成
1、协议——状态码——描述
2、响应头
3、响应实体
同样,来一份Request示例。
HTTP/1.1 200 OKServer: Microsoft-IIS/4.0Date: Mon, 5 Jan 2004 13:13:33 GMTContent-Type: text/htmlLast-Modified: Mon, 5 Jan 2004 13:13:12 GMTContent-Length: 112 <html><head><title>HTTP Response Example</title></head><body>Welcome to Brainy Software</body></html>
对照Request,基本上不用对Response多加解释,开头就是告诉你使用的是HTTP1.1协议版本,请求成功,一切就绪。着重是200这个状态码,对于状态码其实我再熟悉不过了,像404页面就是源于状态码,200表示成功,404表示找不到所请求的资源。
Socket编程
在计算机网络课程中,我们HTTP的本质是基于TCP/IP网络传输的上层应用,其实现是套接字编程,也就是Socket,对应Java中的两大类Socket和ServerSocket
Socket类
创建一个socket,常用的构造方法:
public Socket(java.lang.String host, int port);
创建后,可以通过该实例和远程主机通信。发送字节流通过调用Socket.getOutputStream获得一个OutputStream实例;发送字符文本,从返回的OutputStream实例中构造一个PrintWriter对象;接收字节流通过调用Socket.getIutputStream获得一个OutputStream实例。
下面代码创建了一个socket,通过该socket可与本地HTTP服务器(127.0.0.1表示本地主机)通信,发送一个HTTP请求,并接收返回的响应。这里使用BufferedReader作为缓冲,用StringBuffer保存返回的对象。
Socket socket = new Socket("127.0.0.1", "8080");OutputStream os = socket.getOutputStream();boolean autoflush = true;PrintWriter out = new PrintWriter( socket.getOutputStream(), autoflush);BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() )); // send an HTTP request to the web serverout.println("GET /index.jsp HTTP/1.1");out.println("Host: localhost:8080");out.println("Connection: Close");out.println();// read the responseboolean loop = true;StringBuffer sb = new StringBuffer(8096);while (loop) { if ( in.ready() ) { int i=0; while (i!=-1) { i = in.read(); sb.append((char) i); } loop = false; } Thread.currentThread().sleep(50);}// display the response to the out consoleSystem.out.println(sb.toString());socket.close();
需要指出的是,要从服务器得到正确的响应,所发送的HTTP请求必须遵循HTTP协议(按照该协议,服务器那又发生了什么,参见下节)。这也就是前文要介绍HTTP知识的原因,如果有看HTTP Request一节,就不难明白上面的代码(特别是// send an HTTP request to the web server下面那一大段print)。
ServerSocket类
要实现服务程序,如HTTP服务器或是FTP服务器,就要用到有别于Socket的其他方式。这是因为服务器并不知道客户端什么时候会发送连接,所有必须时刻处于待命状态,也就是必须用到ServerSocket类。一个ServerSocket等待连接请求,连接请求一旦被接收,即创建一个Socket实例和客户端交互。
ServerSocket编程较为复杂。首先要绑定一个IP地址(一般是本机127.0.0.1),注册端口号(默认是80)并监听,指定backlog数,ServerSocket一个重要属性,用以限定最大连接数。常用的构造方法如下:
public ServerSocket(int port, int backLog, InetAddress bindingAddress);
注意到在这个构造方法中,IP地址的绑定用到了一个InetAddress的对象,所以可以用静态方法InetAddress.getByName获得一个该对象,实现如下:
InetAddress.getByName("127.0.0.1");
- 【How Tomcat Works】第一章——一个简易的java web服务实现(上)
- 《How To Tomcat Works》-第一章:一个简单的Web服务器
- 《how tomcat works》第一章 构建一个简单的web服务器
- How tomcat works——1 一个简单的Web Server
- how tomcat works 读书笔记(一)----------一个简单的web服务器
- How Tomcat works之(一个简单的web服务器)
- [How Tomcat Works]第1章 一个简单的Web服务器
- How Tomcat Works(Scala语言) 01 一个简单的Web服务器
- How tomcat works——20 基于JMX的管理
- How tomcat works——引言
- How tomcat works——3 连接器
- How tomcat works——5 容器
- How tomcat works——6 生命周期
- How tomcat works——10 安全性
- How tomcat works——11 StandardWrapper
- How tomcat works——12 StandardContext
- How tomcat works——15 Digester
- How tomcat works——18 部署
- 电子词典开发几个知识点
- 二维码生成原理
- 大量的TIME_WAIT解决办法
- ubuntu下安装net-snmp5.7.1的步骤
- 成员函数和友元函数的选择方案指导原则
- 【How Tomcat Works】第一章——一个简易的java web服务实现(上)
- 给std::swap添加新版本的swap模板
- Eclipse复制maven工程
- 怎样在Word2010中新建样式
- ARM 嵌入式Linux开发-2G 3G无线传输(DTU)和路由器(目录介绍)
- 百度实习1,2,3面-教育知心搜索前端项目组
- 几种将网站设为首页的代码
- leetcode之Reverse Linked List II
- 红米怎么打开USB调试(Android4.2.2),系统中隐藏开发者选项(红米,MTK6589,三星i9500 /S4打开开发者选项)