自己动手写Web容器之TomJetty之三:掀起请求盖头来
来源:互联网 发布:云计算行业赚钱吗? 编辑:程序博客网 时间:2024/06/05 18:29
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229
前面我们对于实现TomJetty做了一些知识铺垫和复习,息知了HTTP请求的头部的组成元素。目前的TomJetty服务器已经能够成功启动,可是请求一旦过来却又看不懂^_^。所以本文就来解析HTTP请求头,剖析它的各部分。让TomJetty服务器能够明白它的意图。
1HTTP请求头解析
(1)编写一个RequestHeader类,用户封装请求头对象。
package cn.lynn.tomjetty;import java.util.HashMap;/** * 封装请求头 * @author lynnli1229 */public class RequestHeader { private String method; private String url; private String protocal; private String accept; private String accept_language; private String user_agent; private String accept_encoding; private String ip; private String port; private String connection; private String cookie; // 存放请求头键值对 private HashMap<String, String> map; // 存放请求头文本 private String txt; // 省略getter()和setter()方法 @Override public String toString() { return "RequestHeader [" + "\n" + method + " " + url + " " + protocal + "\n" + "Accept: " + accept + "\n" + "Accept-Language: " + accept_language + "\n" + "User-Agent: " + user_agent + "\n" + "Accept-Encoding: " + accept_encoding + "\n" + "Host: " + ip + ":" + port + "\n" + "Connection: " + connection + "\n" + "Cookie: " + cookie + "\n" + "]"; }}
(2)设计一个IRequestHeaderParser接口,并声明parse()方法,用于解析请求头文本内容。
package cn.lynn.tomjetty;public interface IReqestHeaderParser { public RequestHeader parse(String txt) throws Exception;}
(3)提供IRequestHeaderParser接口的实现类RequestHeaderParserImpl,用于执行解析操作。注意一下,我们是以IE浏览器请求头为例,其他版本浏览器请求头的参数顺序会有变动,但整体差别不大。
package cn.lynn.tomjetty;import java.util.HashMap;public class RequestHeaderParserImpl implements IReqestHeaderParser { /** * 解析HTTP请求头 */ public RequestHeader parse(String txt) throws Exception { RequestHeader header = new RequestHeader(); header.setTxt(txt); // 截取请求头第一行 String firstLine = txt.substring(0, txt.indexOf("\n")); String method = firstLine.substring(0, firstLine.indexOf(" ")); String url = firstLine.substring(firstLine.indexOf(" ") + 1, firstLine.lastIndexOf(" ")); String protocal = firstLine.substring(firstLine.lastIndexOf(" ") + 1, firstLine.length()); header.setMethod(method);// 获取Accept参数值,存放到RequestHeader对象当中 header.setUrl(url);// 获取Accept参数值,存放到RequestHeader对象当中 header.setProtocal(protocal);// 获取Accept参数值,存放到RequestHeader对象当中 String[] lines = txt.split("\n"); HashMap<String, String> map = new HashMap<String, String>(); // 从请求头第二行开始分隔,因为第一行没有冒号 for (int i = 1; i < lines.length; i++) { String[] result = lines[i].split(": "); map.put(result[0], (result.length <= 1) ? "" : result[1].replace('\n', ' ').trim()); } header.setMap(map); header.setAccept(map.get("Accept")); // 获取Accept参数值,存放到RequestHeader对象当中 header.setAccept_language(map.get("Accept-Language")); // 获取Accept-Language参数值,存放到RequestHeader对象当中 header.setUser_agent(map.get("User-Agent")); // 获取User-Agent参数值,存放到RequestHeader对象当中 header.setAccept_encoding(map.get("Accept-Encoding")); // 获取Accept-Encoding参数值,存放到RequestHeader对象当中 header.setIp(map.get("Host").split(":")[0]); // 获取Host参数的IP参数值,存放到RequestHeader对象当中 header.setPort(map.get("Host").split(":")[1]); // 获取Host参数的Port参数值,存放到RequestHeader对象当中 header.setConnection(map.get("Connection")); // 获取Connection参数值,存放到RequestHeader对象当中 header.setCookie(map.get("Cookie")); // 获取Cookie参数值,存放到RequestHeader对象当中 return header; }}
(4)在TomJetty类的run()方法中加入如下代码,用于将解析请求头的结果打印到控制台上。
try { InputStream in = socket.getInputStream(); // 获取客户端发送的字节流 OutputStream out = socket.getOutputStream(); // 获取服务端响应的字节流 byte[] b = new byte[1024 * 1024]; // 设置字节缓冲区 in.read(b); // 读取客户端字节流(字节流的请求头) String txt = new String(b).trim(); // 将请求头封装成String,准备交给解析器解析 IReqestHeaderParser parser = (IReqestHeaderParser) Class.forName(TomJettyUtil.getValue("tomjetty.requestheader.class")) .newInstance(); // 使用工厂设计模式从tomjetty.config中加载请求头解析器的实例 RequestHeader header = parser.parse(txt); // 终于可以解析了 System.out.println(header);} catch (Exception e) { e.printStackTrace();}
2解析效果展示
在IE浏览器中输入上述地址后,控制台打印如下:
RequestHeader [GET /hello.jsp HTTP/1.1Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/QVOD, application/QVOD, */*Accept-Language: zh-cnUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; KB974488)Accept-Encoding: gzip, deflateHost: 127.0.0.1:9527Connection: Keep-AliveCookie: null]
写到这里,我们终于完成了对HTTP请求头的解析操作,感觉代码比预想的要多,其中字符串的拆分是关键,其他也就没什么了。OK!现在的TomJetty已经能够读懂请求的内容了,接下来就要着手为该请求提供服务了。可是服务的方式有很多种,其中响应静态页面请求就是很基本的一种。所以,在接下来的一节中我们将处理TomJetty服务器响应静态网页请求的问题。
- 自己动手写Web容器之TomJetty之三:掀起请求盖头来
- 自己动手写Web容器之TomJetty之二:开启服务器
- 自己动手写Web容器之TomJetty之五:包装请求参数
- 自己动手写Web容器之TomJetty之一:服务内功经脉
- 自己动手写Web容器之TomJetty之四:静态页面起步
- 自己动手写Web容器之TomJetty之六:动态页面引入
- 掀起你的盖头来之经典拜读
- 敏捷开发系列之旅 第一站(掀起你的盖头来)
- Key/Value之王Memcached初探:一、掀起MC的盖头来
- Key/Value之王Memcached初探:一、掀起MC的盖头来
- Java之旅Spring框架学习(1)——掀起你的盖头来
- Key/Value之王Memcached初探:一、掀起Memcached的盖头来
- 掀起你的盖头来
- 掀起计算机的盖头来——简评《编程卓越之道 第一卷 深入理解计算机》
- VC++,掀起你的盖头来(zt)
- VC++,掀起你的盖头来
- VC++,掀起你的盖头来
- VC++,掀起你的盖头来
- 谁能帮我缕一缕这些技术的关系?有关数据中心,高并发,大规模数据存储
- QQ2013协议分析(五)0826 Login verify
- 我所理解的设计模式(C++实现)——命令模式(Command Pattern)
- Posix消息队列——mq_notify函数
- Android Activity切换动画(解决back键后退失效问题)
- 自己动手写Web容器之TomJetty之三:掀起请求盖头来
- android Activity生命周期
- 学习算法之路
- C#显示图像
- ERROR LNK 2005
- ORA-12170 TNS 连接超时 .
- 自制编译器:后端代码生成(一)
- 错过
- JAVA编程中,什么是用-Xlint选项编译