gpt4 book ai didi

java - HTTP请求压缩

转载 作者:搜寻专家 更新时间:2023-11-01 01:21:43 26 4
gpt4 key购买 nike

一般用例

想象一个正在上传大量 JSON 的客户端。 Content-Type 应该保留为 application/json 因为它描述了实际数据。 Accept-Encoding 和 Transfer-Encoding 似乎是为了告诉服务器应该如何格式化响应。似乎响应为此明确使用了 Content-Encoding header ,但它不是有效的请求 header 。

有什么我想念的吗?有没有人找到一个优雅的解决方案?

特定用例

我的用例是我有一个移动应用程序生成大量 JSON(在某些情况下还生成一些二进制数据,但程度较小)并且压缩请求可以节省大量量带宽。我使用 Tomcat 作为我的 Servlet 容器。我将 Spring 用于其 MVC 注释,主要是为了将一些 JEE 内容抽象成一个更清晰、基于注释的接口(interface)。我还使用 Jackson 进行自动(反)序列化。

我也使用 nginx,但我不确定这是否是我希望解压发生的地方。 nginx 节点简单地平衡请求,然后通过数据中心分发这些请求。在它实际到达将要处理它的节点之前一直保持压缩状态会很好。

提前致谢

约翰

编辑:

我和@DaSourcerer 之间的讨论对那些在撰写本文时对事物状态感到好奇的人非常有帮助。

我最终实现了自己的解决方案。请注意,这指定了分支“ohmage-3.0”,但它很快就会被合并到 master 分支中。您可能想在那里查看我是否进行了任何更新/修复。

https://github.com/ohmage/server/blob/ohmage-3.0/src/org/ohmage/servlet/filter/DecompressionFilter.java

最佳答案

因为原代码已经不可用了。万一有人来这里需要它。我使用“Content-Encoding: gzip”来识别过滤器是否需要解压。

这是代码。

 @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest httpServletRequest = (HttpServletRequest) request;

String contentEncoding = httpServletRequest.getHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.indexOf("gzip") > -1)
{
try
{
final InputStream decompressStream = StreamHelper.decompressStream(httpServletRequest.getInputStream());

httpServletRequest = new HttpServletRequestWrapper(httpServletRequest)
{

@Override
public ServletInputStream getInputStream() throws IOException
{
return new DecompressServletInputStream(decompressStream);
}

@Override
public BufferedReader getReader() throws IOException
{
return new BufferedReader(new InputStreamReader(decompressStream));
}
};
}
catch (IOException e)
{
mLogger.error("error while handling the request", e);
}
}

chain.doFilter(httpServletRequest, response);
}

简单的 ServletInputStream 包装类

public static class DecompressServletInputStream extends ServletInputStream
{
private InputStream inputStream;

public DecompressServletInputStream(InputStream input)
{
inputStream = input;

}

@Override
public int read() throws IOException
{
return inputStream.read();
}

}

解压流代码

public class StreamHelper
{

/**
* Gzip magic number, fixed values in the beginning to identify the gzip
* format <br>
* http://www.gzip.org/zlib/rfc-gzip.html#file-format
*/
private static final byte GZIP_ID1 = 0x1f;
/**
* Gzip magic number, fixed values in the beginning to identify the gzip
* format <br>
* http://www.gzip.org/zlib/rfc-gzip.html#file-format
*/
private static final byte GZIP_ID2 = (byte) 0x8b;

/**
* Return decompression input stream if needed.
*
* @param input
* original stream
* @return decompression stream
* @throws IOException
* exception while reading the input
*/
public static InputStream decompressStream(InputStream input) throws IOException
{
PushbackInputStream pushbackInput = new PushbackInputStream(input, 2);

byte[] signature = new byte[2];
pushbackInput.read(signature);
pushbackInput.unread(signature);

if (signature[0] == GZIP_ID1 && signature[1] == GZIP_ID2)
{
return new GZIPInputStream(pushbackInput);
}
return pushbackInput;
}
}

关于java - HTTP请求压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20507007/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com