检测HTTP请求(Java套接字)最简单的方法结束?

时间:2014-10-08 07:14:24

标签: java sockets

我必须使用Java套接字来发送和接收HTTP请求(我必须!)。因此,我正在寻找一个考虑content-lengthTransfer-Encoding: chunked等的解决方案......以确定HTTP请求何时结束。

这是我到目前为止所提出的一个例子:

    public String getWebpage()
    {
        try{

            _out.print("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n");
            _out.flush();

            String fullRequest = "";
            String line = null;
            while (( line = _in.readLine()) != null)
            {
                fullRequest += line + "\r\n";
                if(isFullRequest(fullRequest))
                {
                    System.out.println(fullRequest);
                    return fullRequest;
                }
            }            

        }catch(Exception e){}

        return null;
    }

    private boolean isFullRequest(String request)
    {
        return request.contains("\r\n\r\n") //Make sure we have the headers
            && request.contains("</html>"); //Make sure we have the html
    }

我的isFullRequest()方法是检测请求结束的一种非常便宜的方法,但不可靠。

我没有重新发明轮子并花费无数个小时进行调试,而是询问Java中已经包含的类或方法是否完全符合我的要求?没有额外的不必要的jar依赖?

2 个答案:

答案 0 :(得分:4)

如果您不想使用现有的HTTP库,则仅更容易发出HTTP / 1.0请求,以便您不会获得分块响应(仅为HTTP / 1.1定义了chunked)。也不要使用keep-alive,它是HTTP / 1.1隐含的,而不是HTTP / 1.0。总之,请按照以下方式提出您的要求:

GET /page HTTP/1.0
Host: hostname

然后只需读取响应直到数据结束。由于保持活动默认情况下使用HTTP / 1.0关闭,服务器将在响应完成后关闭连接,并且由于HTTP / 1.0不支持分块,因此您也不必担心这一点。

答案 1 :(得分:0)

您可以使用HttpUrlConnection来阅读分块响应。这样您就不必担心检测到请求的结束。

URL url = new URL(urlStr);
HttpURLConnection uc = (HttpURLConnection)url.openConnection();
InputStream in = uc.getInputStream();
byte[] b=new byte[512*1024];
int len;
OutputStream out = new FileOutputStream(f);

while((len=in.read(b))!=-1){
   out.write(b,0,len);
}
out.flush();
out.close();
in.close();

如果您想获得内容长度,可以尝试:

long contentLength = uc.getContentLengthLong()

仅当content-length标题已知时才会有效。

如果不知道还有另一种方式(虽然不是我最喜欢的......)。只需知道内容长度,就可以阅读一次流。 我在一个项目中使用它,在下载页面内容时必须绘制进度条。

long max = uc.getContentLengthLong();
if(max==-1){
    max=0;
    if(in.markSupported()){
        in.mark(1000000000);    //max nb of bytes to be read
        while((len=in.read(b))!=-1){
            max+=len;
        }
        in.reset();
    }
}