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中得到一个错误:not gzip格式(因为在body中找不到gzip头)。
以下是我的想法:
•body.tobyte()是否错误,因为它已被bufferreader作为字符串读取,因此将其转换回byte[]没有意义,因为它已被错误地解释?或者我是否以错误的方式将sting body重新转换为byte[]?
•我是否必须自己使用http头中提供的信息构建gzip头并将其添加到字符串体中?
•我是否需要从socket.getinputstream()创建另一个inputstream来逐字节读取信息,还是因为已经有一个缓冲区“连接”到此socket而很棘手?
1条答案
按热度按时间q5lcpyga1#
大致上,我有一个bufferreader,它允许我从套接字读取几行http响应。
您已经手动启动了一个http客户端。
这不是一件好事;http比你想象的要复杂得多。gzip只是你需要考虑的10000件事情之一。还有http/2.0、spdy、http3、分块传输编码、tls、重定向、mime打包等等。
因此,如果你想编写一个真正的http客户机,你需要大约100倍的代码和大量的领域知识,因为http协议的实际规范虽然很方便,但并不能真正说明问题。事实上,您正在实现的协议是“连接到internet的服务器倾向于发送的任何内容”,它们倾向于发送的内容与“常用浏览器倾向于正确的任何内容”紧密相连,这几乎是,但不完全是规范文档所说的。在这种情况下,语用学和实现是“真正的规范”,而真正的规范只是试图记录现实。
这是一个很长的路要说:你的错误是试图手卷http客户端。别那么做。在核心库中使用okhttp或jdk11中引入的http客户机。
但是,我知道我想要什么!
不过,你的代码中有很多bug。
datainputstream response=新的datainputstream(clientsidesocket.getinputstream());
datainputstream在这里是无用的。把 Package 纸取下来。
bufferedreader buffer=新的bufferedreader(新的inputstreamreader(响应))
缺少分号。此外,这是打破-这将转换的字节流通过电线字符使用'平台默认编码'这是错误的,你需要看看内容类型的标题。
responsebody=解压(responsebody)
你不能这样做。你的主要误解是你似乎认为一堆字节和一系列字符之间没有区别。
那是错误的。一旦将字节存储到字符中,就不能再解压缩它了。
解决方法是首先检查gzip头,然后通过gzipstream Package inputstream。