当前位置: 首页 > 知识库问答 >
问题:

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

曾航
2023-03-14

我正在尝试编写一个简单的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。玻璃鱼。灰熊http。gzip内容编码

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


共有1个答案

潘俊
2023-03-14

我在泽西图书馆找到的。对于服务器端,需要进行以下配置:

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

在convers下,EncodingFilter#enableFor(ResourceConfig.Class

我想在注册过程中绕道的原因在于,任何编码都需要分两个阶段进行。首先是编码过滤器(这是一个实际的ContainerResponseFilter通过将Content Encoding设置为gzip来修改响应的标题。同时,筛选器无法修改消息体的实体流,因为在创建流之前就调用了筛选器。因此,必须对流进行修改由WriterInterceptor触发,该程序在过滤器处理后以及实体流创建后触发。

因此,当客户端将Content Encoding头设置为gzip时,仅注册GZipEncoder将用于请求解码,这与服务器的创建无关。

我用“GZipWriterInterceptor”给出的示例基本上是编码过滤器的一个实现较差的版本。当然,头应该在过滤器中设置,而不是在拦截器中设置。文件中说:

过滤器主要用于操作HTTP头、URI和/或HTTP方法等请求和响应参数,而拦截器则用于通过操作实体输入/输出流来操作实体

因此,gzip编码不能简单地通过注册一个GZipEncoder来激活,它还需要注册一个过滤器。这就是为什么我希望两者都捆绑在功能中的原因。

重要提示:Jersey中有两个EncodingFilter类。一个属于客户机,另一个属于服务器实现。不要使用错误的,因为他们做的事情根本不同。不幸的是,在运行单元测试时,您的类路径上会同时包含这两个元素,因为它们依赖于客户机接口。

 类似资料:
  • 问题内容: 我正在使用php的功能来执行HTTP请求。为了节省带宽,我决定使用添加标题。 显然,输出一个gzip编码的字符串,所以我用来解码该编码的字符串,但是将作为参数传递的数据出错。 我知道还有另一个功能可以解压缩压缩后的数据,但是它不包含在我的PHP版本中(也许仅在SVN上可用)。 我知道cUrl可以即时解码gzip流(没有任何问题),但是有人建议我使用它而不是cUrl。 您是否知道以其他方

  • 问题内容: 我有一个用rails编写的api,它在每个请求上均以JSON响应进行响应。 响应可能很大,因此我需要使用gzip压缩JSON响应。 想知道如何在Rails控制器中执行此操作? 我加了线 在config.ru中 我还应该在呈现JSON的行中更改某些内容吗? 另外,我如何检查响应是否为gzip格式。 我从终端发出了curl请求,我只看到普通的普通JSON。 问题答案: 对于以gzip格式的

  • 问题内容: Gzip格式文件(gzip例如,使用程序创建的文件)使用“放气”压缩算法,该压缩算法与zlib使用的压缩算法相同。但是,使用zlib膨胀gzip压缩文件时,该库将返回Z_DATA_ERROR。 如何使用zlib解压缩gzip文件? 问题答案: python zlib库支持: RFC 1950(zlib压缩格式) RFC 1951(deflate压缩格式) RFC 1952(gzip压缩

  • 我试图启用gzip压缩的组件我的网站。我有ubuntu 11.04服务器和nginx 1.2。 在网站的nginx配置中,我有以下内容 Yslow和谷歌的速度测量建议我使用gzip来减少网络传输。现在,当我尝试时,我得到了 是否知道我做错了什么,或者我应该做什么来获得压缩内容?

  • 问题内容: 我是Go的新手,无法弄清楚如何使用该软件包对我有利。基本上,我只想写一些东西到文件中,将其gzip压缩,然后通过另一个脚本直接从压缩格式读取。如果有人可以给我一个有关如何执行此操作的示例,我将不胜感激。 问题答案: 所有压缩包都实现相同的接口。您将使用以下方式进行压缩: 并解压缩:

  • 问题内容: JSON.stringify显然不是非常节省空间。例如,当[123456789,123456789]可能需要大约5个字节时,它将占用20+字节。websocket是否在发送到流之前压缩其JSON? 问题答案: 从本质上讲,WebSocket只是用于TEXT或BINARY数据的一组框架。 它本身不执行压缩。 但是,WebSocket规范允许扩展,并且野外有各种各样的压缩扩展(其中一项的正