JAVA_MZD 2010-11-15 13:18
浏览 799
已采纳

用java解析HTTP请求报头

在上次WEB项目的总结中

我就已经花了很多时间

总结了HTTP协议

详细的叙述了HTTP请求,应答

并用Telnet自己写过一个HTTP请求

 

这次

在山寨Tomcat雏形的时候

因为需要服务器端

根据请求的信息

作出相应回应

 

而请求信息

又都是通过浏览器封装好的

Http请求类型

 

 

在服务器端

通过一个客户线程

使用客户线程的输入流

即可完全得到

经过浏览器封装好的

向服务器端发送的信息

源代码如下

  /**
     * 传入一个Socket对象,解析出通过该对象传入这个链接中的所有HTTP请求信息
     * 
     * @param client
     */
    private void getRequset(Socket client) {
        try {
            InputStream in = client.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);
            BufferedReader bd = new BufferedReader(reader);//三重封装
            String t = null;

            while ((t = bd.readLine()) != null) {
                System.out.println(t);
                                                          parser(t);//解析每一句的方法
            }
        } catch (Exception ef) {
            ef.printStackTrace();
            System.out.println("getRequset error--->");
        }
    }

 

 

信息如下

GET /index HTTP/1.1
User-Agent: Opera/9.80 (Windows NT 6.1; U; Edition IBIS; zh-cn) Presto/2.6.30 Version/10.63
Host: localhost:81
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Connection: Keep-Alive
//注意,此处两行空格也为HTTP请求的一部分

 

 

我们又都知道

在Tomcat中

所有的请求信息

 

我们都已经封装好

放入一个HttpRequest对象中

 

在我们自己山寨的Tomcat中

因为得到的Http请求是一个字符串

要得到我们需要的信息

 

也必须对此字符串进行解析

将解析后的字符串放入一个Request对象中

 

Requst类源码如下

public class Request {
    private String method;// 请求方法
    private String protocol;// 协议版本
    private String requestURL;
    private String requestURI;//请求的URI地址  在HTTP请求的第一行的请求方法后面
    private String host;//请求的主机信息
    private String Connection;//Http请求连接状态信息 对应HTTP请求中的Connection
    private String agent;// 代理,用来标识代理的浏览器信息 ,对应HTTP请求中的User-Agent:
    private String language;//对应Accept-Language
    private String encoding;//请求的编码方式  对应HTTP请求中的Accept-Encoding
    private String charset;//请求的字符编码  对应HTTP请求中的Accept-Charset
    private String accept;// 对应HTTP请求中的Accept;


getter()  setter()

}

 

  有了用来存放封装后信息的Request类

  有了请求信息的字符串

  接下来

  我们只需要将字符串解析

  并且存放在Request对象中

 

 源代码如下

 

  /**
     * 传入HTTP请求中需要解析的某一句 解析该句,并请放入对应的Request对象中
     * 
     * @param s
     */
    private void parser(String s) {
        if (s.startsWith("GET")) {
            String method = "Get";
            request.setMethod(method);

            int index = s.indexOf("HTTP");
            System.out.println("index--->" + index);
            String uri = s.substring(3 + 1, index - 1);// 用index-1可以去掉连接中的空格
            System.out.println("uri--->" + uri);
            request.setRequestURI(uri);

            String protocol = s.substring(index);
            System.out.println("protocol---->" + protocol);
            request.setProtocol(protocol);
        } else if (s.startsWith("POST")) {
            String method = "POST";
            request.setMethod(method);

            int index = s.indexOf("HTTP");
            System.out.println("index--->" + index);
            String uri = s.substring(3 + 1, index - 1);// 用index-1可以去掉连接中的空格
            System.out.println("uri--->" + uri);
            request.setRequestURI(uri);

            String protocol = s.substring(index);
            System.out.println("protocol---->" + protocol);
            request.setProtocol(protocol);

        } else if (s.startsWith("Accept:")) {
                String accept = s.substring("Accept:".length() + 1);
            System.out.println("accept--->" + accept);
            request.setAccept(accept);

        } else if (s.startsWith("User-Agent:")) {
            String agent = s.substring("User-Agent:".length() + 1);
            System.out.println("agent--->" + agent);
            request.setAgent(agent);

        } else if (s.startsWith("Host:")) {
            String host = s.substring("Host:".length() + 1);
            System.out.println("host--->" + host);
            request.setHost(host);

        } else if (s.startsWith("Accept-Language:")) {
            String language = s.substring("Accept-Language:".length() + 1);
            System.out.println("language--->" + language);
            request.setLanguage(language);

        } else if (s.startsWith("Accept-Charset:")) {
            String charset = s.substring("Accept-Charset:".length() + 1);
            System.out.println("charset--->" + charset);
            request.setCharset(charset);
        } else if (s.startsWith("Accept-Encoding:")) {
            String encoding = s.substring("Accept-Encoding:".length() + 1);
            System.out.println("encoding--->" + encoding);
            request.setEncoding(encoding);

        } else if (s.startsWith("Connection:")) {
            String connection = s.substring("Connection:".length() + 1);
            System.out.println("connection--->" + connection);
            request.setConnection(connection);
        }

    }

   封装好请求的Request对象后

  接下来

  我们就来封装进行应答的Response对象

 

  MOVE ON


问题补充
lihuan5120 写道
看楼主的头像。。。该不会是长沙理工大学的吧???

中南
问题补充
http4j 写道
鼓励一下,多写写协议级的纯Java代码会提高些水准。目前我和楼主相反,在研究纯Client端的Java HTTP。楼主可以借鉴Apache HTTP Component.
不过有一点建议,楼主你的If-else能不能处理一下,这种代码太让人眼花缭乱了。
我给你个建议,用Annotation对Request中字段进行标注,比如charset可以标注@RequestAttribute(name="Accept-Charset"),通过反射自动根据标注名称赋值。

我写的纯client在http://code.google.com/p/http4j
欢迎多多交流。


感谢兄弟的指导,受教了。
  • 写回答

9条回答 默认 最新

  • http4j 2010-11-15 13:18
    关注

    鼓励一下,多写写协议级的纯Java代码会提高些水准。目前我和楼主相反,在研究纯Client端的Java HTTP。楼主可以借鉴Apache HTTP Component.
    不过有一点建议,楼主你的If-else能不能处理一下,这种代码太让人眼花缭乱了。
    我给你个建议,用Annotation对Request中字段进行标注,比如charset可以标注@RequestAttribute(name="Accept-Charset"),通过反射自动根据标注名称赋值。

    我写的纯client在http://code.google.com/p/http4j
    欢迎多多交流。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(8条)

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!