【问题标题】:Gzip Format Decompress - JerseyGzip 格式解压缩 - 泽西岛
【发布时间】:2014-08-29 00:48:09
【问题描述】:

我正在将 Json 压缩成 Gzip 格式并发送如下:

connection.setDoOutput(true); // sets POST method implicitly
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Content-Encoding", "gzip"); 

final byte[] originalBytes = body.getBytes("UTF-8"); 
final ByteArrayOutputStream baos = new ByteArrayOutputStream(originalBytes.length);
final ByteArrayEntity postBody = new ByteArrayEntity(baos.toByteArray());                       
method.setEntity(postBody);

我想接收 Post 请求并将其解压缩为字符串。我应该使用什么 @Consumes 注释。

【问题讨论】:

    标签: java rest jersey jax-rs


    【解决方案1】:

    您可以使用ReaderInterceptor 为您的资源类(如described in the docmentation)处理透明的gzip 编码。 拦截器可能如下所示:

    @Provider
    public class GzipReaderInterceptor implements ReaderInterceptor {
    
        @Override
        public Object aroundReadFrom(ReaderInterceptorContext context)  throws IOException, WebApplicationException {
            if ("gzip".equals(context.getHeaders().get("Content-Encoding"))) {
                InputStream originalInputStream = context.getInputStream();
                context.setInputStream(new GZIPInputStream(originalInputStream));
            }
            return context.proceed();
        }
    
    }
    

    对于您的资源类,gzipping 是透明的。它仍然可以消耗application/json。 您也不需要处理字节数组,只需像往常一样使用 POJO:

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response post(Person person) { /* */ }
    

    一个问题也可能是您的客户端代码。 我不确定你是否真的在压缩帖子正文,所以这里有一个完整的例子,它发布了一个带有 URLConnection 的压缩实体:

    String entity = "{\"firstname\":\"John\",\"lastname\":\"Doe\"}";
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    GZIPOutputStream gzos = new GZIPOutputStream(baos);
    gzos.write(entity.getBytes("UTF-8"));
    gzos.close();
    
    URLConnection connection = new URL("http://whatever").openConnection();
    connection.setDoOutput(true);
    connection.setRequestProperty("Content-Type", "application/json");
    connection.setRequestProperty("Content-Encoding", "gzip");
    connection.connect();
    baos.writeTo(connection.getOutputStream());
    

    【讨论】:

    • 谢谢...但是如何在方法中处理来自拦截器的返回值。
    • 会是这样吗.....public String Gzip(byte[] json) { String str = ... // 很长的字符串 return str; }
    • 如果 originalInputStream 为空(即请求体为空),GZipInputStream 创建将失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    相关资源
    最近更新 更多