解压缩http响应



作为java的初学者,我尝试以Gzip格式解压缩HTTP响应。大致来说,我有一个bufferReader,它允许我从套接字读取http响应的行。多亏了这一点,我解析了http头,如果它指定正文是gzip格式的,那么我必须对它进行解压缩

DataInputStream response = new DataInputStream(clientSideSocket.getInputStream());
BufferedReader buffer = new BufferedReader(new InputStreamReader(response))
header = parseHTTPHeader(buffer);  // return a map<String,String> with header options
StringBuilder SBresponseBody = new StringBuilder();
String responseBody = new String();
String line;
while((line = buffer.readLine())!= null) // extract the body as if was a string...
SBresponseBody.append(line);
responseBody = SBresponseBody.toString();
if (header.get("Content-Encoding").contains("gzip"))
responseBody = unzip(responseBody); // function I try to construct

我对解压功能的尝试如下:

private String unzip(String body) throws IOException {
String responseBody = "";
byte[] readBuffer = new byte[5000];
GZIPInputStream  gzip = new GZIPInputStream (new ByteArrayInputStream(body.getBytes());
int read = gzip.read(readBuffer,0,readBuffer.length);
gzip.close();

byte[] result = Arrays.copyOf(readBuffer, read);

responseBody = new String(result, "UTF-8");
return responseBody;
}

我在GZIPInputStream中得到一个错误:不是GZIP格式(因为在正文中找不到GZIP头(。

以下是我的想法:

•body.toByte((是否错误,因为它已被bufferReader作为字符串读取,因此将其转换回byte[]毫无意义,因为它已经被错误地解释了?还是以错误的方式将Sting正文重新转换为byte[]?

•我是否必须使用HTTP标头中提供的信息自己构建GZIP标头,并将其添加到String主体中?

•我需要从我的socket.getInputStream((创建另一个InputStream来逐字节读取信息,还是因为已经有一个缓冲区而变得棘手;连接的";到这个插座?

大致上,我有一个bufferReader,它允许我从套接字读取http响应行。

您已经手动交付了一个HTTP客户端。

这不是一件好事;HTTP比你想象的要复杂得多。gzip只是你需要考虑的大约10000件事情之一。HTTP/2.0、Spdy、http3、分块传输编码、TLS、重定向、mime打包等等。

因此,如果你想编写一个真正的HTTP客户端,你需要大约100倍的代码和大量的领域知识,因为HTTP协议的实际规范虽然很方便,但并不能真正说明问题。你正在实现的事实上的协议是"连接到互联网的任何服务器都倾向于发送",而他们倾向于发送的内容与"常用浏览器都倾向于正确"紧密相连,这几乎但不完全是规范文件所说的。在这种情况下,语用学和实现是"真正的规范",而实际的规范只是试图记录现实。

这是一个很长的路要走:你的错误是试图移交一个HTTP客户端。不要那样做。在核心库中使用OkHttp或jdk11中引入的http客户端。

但是,我知道我想要什么

不过,您的代码中充满了错误。

DataInputStream响应=新的DataInputStream(clientSideSocket.getInputStream(((;

DataInputStream在这里毫无用处。拆下包装纸。

BufferedReader缓冲区=新的BufferedReader(新的InputStreamReader(响应((

缺少分号。此外,这是坏的-这将使用"平台默认编码"将流经导线的字节转换为字符,这是错误的,您需要查看Content-Type标头。

responseBody=解压缩(responseBody(

您不能这样做。你的主要误解是,你似乎认为一堆字节和一系列字符之间没有区别。

这是错误的。一旦将字节存储到字符中,就不能再对其进行解压缩。

修复方法是检查gzip头FIRST,然后通过GZipStream包装输入流。

最新更新