我正在尝试编写一个简单的 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));
}
}
从记录的转储中,我可以看出请求符合预期:内容编码在标头中发出信号并应用于请求消息正文。Accept-Encoding也已设置。服务器了解应用的 gzip 压缩并解压缩请求消息正文。但是,它忽略了客户端接受压缩响应并发送未压缩的响应消息体这一事实。
当我在-builder 链中添加encoding(ENCODING_GZIP)
第(1)Response
行时,我得到了我正在寻找的结果。但是,我只想在请求中将其标记为可接受的情况下应用编码。此外,我想在广泛的应用程序范围内联合此功能,而不仅仅是针对特定响应。
我当然可以使用以下命令手动添加这样的功能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();
}
}
但我相信这是不必要的样板。
EncodingFeature
似乎只是客户端库的一部分。每当请求通过接受编码建议编码时,我基本上是在寻找一种可能性,使泽西服务器将数据编码为 gzip。
当我尝试在网上搜索解决方案时,我发现很多。他们中的大多数都关注 Jersey 1。其中一些建议向 GrizzlyServer 添加一个侦听器(这将是 Jersey 特定的而不是 JAX-RS?)。然后在 Jersey 2 依赖树中有很多类建议使用 GZip 编码:
org.glassfish.grizzly.http.GZipContentEncoding
org.glassfish.jersey.message.GZipEncoder
org.glassfish.grizzly.compression.zip.GZipEncoder
org.glassfish.grizzly.compression.zip.GZipDecoder
org.glassfish.grizzly.compression.zip.GZipFilter
我发现网络上的人建议使用其中任何一个,尽管我认为这org.glassfish.jersey
似乎是正确的选择,因为它是一个实际的 Jersey 依赖项。ApacheConnector
更不用说在相关库中找到的那些了。我不知道我应该实际使用哪一个。