Glassfish 如何使响应消息体使用GZip压缩
我正在尝试编写一个简单的Jersey应用程序,它将文件从Jersey客户端发送到Jersey服务器并返回。但是,文件似乎只是在从客户端到服务器的过程中编码的,而不是在另一个过程中编码的。我想知道我怎样才能改变这种行为 我用一个简单的例子来测试这一点: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
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+