编写自己的一个简单的web容器(二)
昨天我们已经能够确定浏览器的请求能够被我们自己编写的服务类所接收并且我们服务类响应的数据也能够正常发送到浏览器客户端,那么我们今天要解决的问题就是让我们的数据能够被浏览器识别并解析。
Http(Https)协议
我们发送到浏览器的数据如果想要被浏览器正常的解析,那其必须符合http协议规定的数据格式。其请求信息的格式我们已经能够看到如下所示:
我们来简单的分析一下这个请求头信息
1.首先第一行包含了三个信息 :请求类型:get 请求资源路径和参数:/portal/ 该请求的http协议版本。这是请求信息的头行,三种信息之间同空格分隔格式是固定的,其后跟一个换行符标示投行结束。
2.第二行包含了请求指向的主机地址(ip地址或域名)和端口号,其后仍然是一个换行符。
3.剩下的一直到Cookie都是请求的头信息每行后面同样都跟了一个换行符。
4.请求头信息结束后下面空一行(一个换行符)后另起一行跟的是请求正文信息。如果请求类型为Post且表单存在参数时会产生请求正文信息记录表单中的参数。如下图所示
以上就是http协议中请求的数据格式,然而解决我们的问题还需要知道响应的数据格式,后来我在网上也搜素了一些关于http协议的博客,发现响应信息的数据格式如下图类似
响应头第一行也称为状态行,格式如下(下图中红线标出的那行):HTTP-Version 空格 Status-Code 空格 Reason-Phrase CRLF HTTP- Version表示HTTP版本,例如为HTTP/1.1。Status- Code是结果代码,用三个数字表示。Reason-Phrase是个简单的文本描述,解释Status-Code的具体原因。Status-Code用于机器自动识别,Reason-Phrase用于人工理解。Status-Code的第一个数字代表响应类别,可能取5个不同的值。后两个数字没有分类作用。Status-Code的第一个数字代表响应的类别,后续两位描述在该类响应下发生的具体状况,具体请参见:HTTP状态码 。
关于更多http协议的内容推荐大家去这个博客查看:《HTTP协议详解》,
修改之前的代码并测试
在知道了http协议的护具格式之后我们修改之前的代码来进行测试
1 package cn.wz.net.demo; 2 3 import java.io.DataInputStream; 4 import java.io.DataOutputStream; 5 import java.io.IOException; 6 import java.io.PrintStream; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 import java.util.Date; 10 11 /** 12 * Created by WangZhe on 2017/5/17. 13 */ 14 public class SocketServer { 15 public static void main(String[] args) throws IOException { 16 ServerSocket server = new ServerSocket(7777); 17 Socket accept = server.accept(); 18 DataInputStream dis = new DataInputStream(accept.getInputStream()); 19 byte[] data=new byte[20480]; 20 dis.read(data); 21 String requserInfo=new String(data); 22 System.out.println(requserInfo); 23 DataOutputStream dos = new DataOutputStream(accept.getOutputStream()); 24 String html="<html> <head><title>测试</title></head> <body><div>测试页面</div></body></html>"; 25 StringBuffer responseHead=new StringBuffer(); 26 responseHead.append("HTTP/1.1 200 OK\r\n"); 27 responseHead.append("Server:WZ tomact/0.0.01").append("\r\n"); 28 responseHead.append("Data:").append(new Date()).append("\r\n"); 29 responseHead.append("Content-type:text/html;charset=UTF-8").append("\r\n"); 30 responseHead.append("Content-Length:").append(html.getBytes().length).append("\r\n"); 31 responseHead.append("\r\n"); 32 responseHead.append(html); 33 dos.writeUTF(responseHead.toString()); 34 dos.flush(); 35 dos.close(); 36 dis.close(); 37 accept.close(); 38 server.close(); 39 } 40 }
运行该类,浏览器请求后的结果如下:
好了到这里我们的web容器已经说是用一个很好的开端了,在接下来的系列博客中我也会一步步的对请求(request)、响应(response)
进行封装,包括解析请求信息,以及如何响应我们已经编写好的html文件给浏览器以及控制器的编写等。请大家持续关注,多多指点,谢谢