Java 解压缩http响应

Java 解压缩http响应,java,http,gzip,unzip,Java,Http,Gzip,Unzip,java初学者,我尝试以Gzip格式解压缩HTTP响应。大致上,我有一个bufferReader,它允许我从套接字读取http响应行。多亏了这一点,我解析了http头,如果它指定主体是gzip格式的,那么我必须解压缩它。以下是我使用的代码: DataInputStream response = new DataInputStream(clientSideSocket.getInputStream()); BufferedReader buffer = new BufferedReader(new

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
我在GZIPInputStream中得到一个错误:不是GZIP格式(因为在正文中找不到GZIP头)

以下是我的想法:

•body.toByte()是否错误,因为它已被bufferReader作为字符串读取,因此将其转换回byte[]没有意义,因为它已被错误地解释?或者我是否以错误的方式将Sting body重新转换为字节[]

•我是否必须自己使用HTTP头中提供的信息构建GZIP头并将其添加到字符串体中

•我是否需要从socket.getInputStream()创建另一个InputStream来逐字节读取信息,还是因为已经有一个缓冲区“连接”到此socket而很棘手

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

您已经手动滚动了一个HTTP客户端

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

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

要说这一点还有很长的路要走:您的错误是尝试使用HTTP客户端。不要那样做。在核心库中使用或使用jdk11中引入的

但是,我知道我想要什么! 但是,您的代码中充满了bug

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

DataInputStream在这里是无用的。取下包装纸

BufferedReader buffer=新的BufferedReader(新的InputStreamReader(响应))

缺少分号。此外,这是错误的-这将使用“平台默认编码”将流经线路的字节转换为字符,这是错误的,您需要查看内容类型标题

responseBody=解压缩(responseBody)

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

那是错误的。一旦将字节存储到字符中,就无法再解压缩它了


解决方法是首先检查gzip头,然后通过GZipStream包装您的inputstream。

这是否回答了您的问题?
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;
}