Glassfish 如何使响应消息体使用GZip压缩

Glassfish 如何使响应消息体使用GZip压缩,glassfish,jersey,jax-rs,Glassfish,Jersey,Jax Rs,我正在尝试编写一个简单的Jersey应用程序,它将文件从Jersey客户端发送到Jersey服务器并返回。但是,文件似乎只是在从客户端到服务器的过程中编码的,而不是在另一个过程中编码的。我想知道我怎样才能改变这种行为 我用一个简单的例子来测试这一点: public class GZipEncodingTest extends JerseyTest { private static final String PATH = "/"; private static final String

我正在尝试编写一个简单的Jersey应用程序,它将文件从Jersey客户端发送到Jersey服务器并返回。但是,文件似乎只是在从客户端到服务器的过程中编码的,而不是在另一个过程中编码的。我想知道我怎样才能改变这种行为

我用一个简单的例子来测试这一点:

public class GZipEncodingTest extends JerseyTest {

  private static final String PATH = "/";
  private static final String QUESTION = "foo", ANSWER = "bar";
  private static final String ENCODING_GZIP = "gzip";

  @Path(PATH)
  public static class MyResource {
    @POST
    public Response handle(String question) throws IOException {
      assertEquals(QUESTION, question);
      return Response.ok(ANSWER).build(); // (1)
    }
  }

  @Override
  protected Application configure() {
    enable(TestProperties.LOG_TRAFFIC);
    enable(TestProperties.DUMP_ENTITY);
    return new ResourceConfig(MyResource.class, GZipEncoder.class);
  }

  @Override
  @SuppressWarnings("unchecked")
  protected void configureClient(ClientConfig config) {
    config.register(new EncodingFeature(ENCODING_GZIP, GZipEncoder.class));
  }

  @Test
  public void testHeaders() throws Exception {
    Response response = target().path(PATH).request().post(Entity.text(QUESTION));
    assertEquals(ANSWER, response.readEntity(String.class));
  }
}
从记录的转储中,我可以看出请求是按预期进行的:内容编码在头中发出信号,并应用于请求消息体。还设置了接受编码。服务器理解应用的gzip压缩并解压缩请求消息体。但是,它忽略了这样一个事实,即客户机接受gzip响应并发送未压缩的响应消息体

当我在
响应
-builder链的第(1)行追加
编码(encodinggzip)
时,我得到了我想要的结果。但是,我只想在请求中标记为可接受时应用编码。此外,我希望在整个应用程序范围内使用此功能,而不仅仅是针对特定的响应

当然,我可以使用
WriterInterceptor
手动添加这样的功能:

public class GZipWriterInterceptor implements WriterInterceptor {
  @Override
  public void aroundWriteTo(WriterInterceptorContext context) 
      throws IOException, WebApplicationException {
    context.getHeaders().add(HttpHeaders.CONTENT_ENCODING, ENCODING_GZIP);
    context.proceed();
  }
}
但我相信,这是不必要的锅炉板

编码功能似乎只是客户端库的一部分。我基本上是在寻找一种可能性,让Jersey服务器在请求建议通过accept编码时将数据编码为gzip

当我试图在网上搜索解决方案时,我发现了很多。其中大部分涉及泽西1号。其中一些人建议在GrizzlyServer中添加一个侦听器(这是特定于Jersey的,而不是JAX-RS?)。Jersey 2依赖树中有很多类建议使用GZip编码:

  • org.glassfish.grizzly.http.gzip内容编码
  • org.glassfish.jersey.message.GZipEncoder
  • org.glassfish.grizzly.compression.zip.GZipEncoder
  • org.glassfish.grizzly.compression.zip.gzip解码器
  • org.glassfish.grizzly.compression.zip.gzip过滤器

我发现网络上的人建议使用其中任何一种,尽管我认为
org.glassfish.jersey
似乎是正确的选择,因为它实际上是一种jersey依赖。更不用说那些在
ApacheConnector
相关库中找到的。我不知道我到底应该用哪一个。

我通过查看泽西岛图书馆找到了答案。对于服务器端,需要进行以下配置:

@Override
@SuppressWarnings("unchecked")
protected Application configure() {
    ResourceConfig resourceConfig = new ResourceConfig(MyResource.class);
    EncodingFilter.enableFor(resourceConfig, GZipEncoder.class);
    return resourceConfig;
}

在相反的模式下,
EncodingFilter#enableFor(ResourceConfig.ClassSee,我的问题实际上有点复杂。我想重建gzip编码。我在这里重申了我的问题:我仍然试图通过让gzip示例工作来重建这个问题的正式解决方案。但是,我只是以一种方式工作,而不是另一种方式。您建议的解决方案看起来像是对我,说实话,这太糟糕了…这个解决方案只适用于Jersey 2.0+