如何确保您已阅读"完整信息"当使用"转移编码:chunked" http响应

时间:2015-10-23 13:09:59

标签: httpurlconnection chunked

我正在使用HttpUrlConnection(java)来读取http chunked响应(Transfer-Encoding:chunked),如下所示,我能够阅读该消息。但是,我怎样才能确保我已正确读取所有块并且读取的消息完好无损..

BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

1 个答案:

答案 0 :(得分:0)

嘿,我很抱歉迟到的回复,但正如你可能猜到的那样,我只是遇到了你的问题。

您似乎对分块传输编码意味着什么有一点误解。 这并不意味着消息将以CRLF结束的行发送。 这似乎是你想要实现的,但它比这复杂一点。

如果你不熟悉CRLF是什么,它只是意味着Carriage-Return Line-Feed(或传统Unix转义序列中的\r\n)。

分块传输编码意味着消息将以而不是行发送。每个块的格式都比以CRLF结尾的行更加自我解释。

Chunks如何运作

每个块以[0-9,'a' - 'f']范围内的一系列字符开头。这是一个十六进制数字,表示块的长度(以字节为单位)。这个十六进制数字后跟一个CRLF。接下来是块数据(希望具有指定的长度)。块数据将以另一个CRLF结束。

你将按顺序获得这些块中的几个,并且按照它们到达的顺序连接它们是你的工作。你按顺序阅读它们,直到你得到一个特殊的块来表示消息体的结尾。关于最后一个块的唯一特别之处是它的长度为零且不包含数据,即块将为0\r\n\r\n

不幸的是,Java的HttpURLConnection类只实现了自动分块传输编码,你必须自己进行解码。

尽管很麻烦,如果你实施这个协议,你可以确信你是否已经阅读了整个消息......但有一点需要注意......

您可能需要查找预告片

预告片与标题相同,只是它们来自HTTP消息的 end ,而标题出现在开头。分块传输编码将允许您查找消息正文的结尾,但完整的HTTP消息可能会继续。

HttpURLConnection类不会为您解析预告片。该类在将其套接字(或其使用的任何内容)定向到连接的OutputStream之前解析HTTP头(状态行和标题)。一旦套接字指向该OutputStream,它就不会返回。从那时起,您可以自行处理数据。

幸运的是,预告片比标题更容易预测......或者至少它们应该是。服务器将发送的每个预告片应该在Trailers标题字段中以分号分隔的列表中指定,即标题中的Trailers: Content-disposition; Cache-control; From表示您应该查找Content-disposition,{{1}邮件之后的{}和Cache-control个预告字段。

只允许在分块编码消息中使用预告片,它们采用与标题相同的格式:字段名称,冒号,空格,字段值,CRLF。就像标题一样,如果预告片后跟两个CRLF而不是一个,这意味着它是最后一个预告片。