为什么泽西岛会吞下我的“内容编码"?标题 [英] Why does Jersey swallow my "Content-Encoding" header

查看:19
本文介绍了为什么泽西岛会吞下我的“内容编码"?标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么下面的示例会在请求中吞下我的Content-Encoding"的 HTTP-Header.我正在编写一个需要解码自定义编码格式的应用程序.但是,我永远无法从请求中获取Content-Encoding"标头.既不在实际资源中,也不在 ReaderInterceptor 中.在响应中,这个编码头没有被吞掉.

Why does the following example swallow my HTTP-Header for "Content-Encoding" in the request. I am writing an application where I need to decode a custom encoding format. However, I can never get hold of the "Content-Encoding" header from the request. Neither in the actual resource nor in an ReaderInterceptor. In the response, this encoding header is not swallowed.

在以下(可运行的)示例中可以很容易地观察到这种行为:

This behavior can be easily observed in the following (runnable) example:

public class Demo extends JerseyTest {
  @Override
  protected Application configure() {
    enable(TestProperties.DUMP_ENTITY);
    enable(TestProperties.LOG_TRAFFIC);
    return new ResourceConfig(MyResource.class, MyInterceptor.class);
  }

  public static final String PATH = "path";
  public static final String ENCODING = "my-encoding";
  public static final String CUSTOM_HEADER = "X-Content-Encoding";
  public static final String QUESTION = "question", ANSWER = "answer";

  @Path(PATH)
  public static class MyResource {
    @POST
    public Response handle(String value, @Context HttpHeaders httpHeaders) {
      assertEquals(ENCODING, httpHeaders.getHeaderString(CUSTOM_HEADER));
      // Here, the "Content-Encoding" header mysteriously disappeared.
      assertEquals(ENCODING, httpHeaders.getHeaderString(HttpHeaders.CONTENT_ENCODING));
      return Response
          .ok(ANSWER)
          .header(CUSTOM_HEADER, ENCODING)
          .header(HttpHeaders.CONTENT_ENCODING, ENCODING)
          .build();
    }
  }

  public static class MyInterceptor implements ReaderInterceptor, WriterInterceptor {
    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context) 
        throws IOException, WebApplicationException {
      assertEquals(ENCODING, context.getHeaders().getFirst(CUSTOM_HEADER));
      // Here, the "Content-Encoding" header mysteriously disappeared.
      assertEquals(ENCODING, context.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING));
      return context.proceed();
    }

    @Override
    public void aroundWriteTo(WriterInterceptorContext context) 
        throws IOException, WebApplicationException {
      assertEquals(ENCODING, context.getHeaders().getFirst(CUSTOM_HEADER));
      // Here, the "Content-Encoding" header can be found.
      assertEquals(ENCODING, context.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING));
      context.proceed();
    }
  }

  @Test
  public void test() throws Exception {
    Response response = target(PATH)
        .request()
        .header(CUSTOM_HEADER, ENCODING)
        .header(HttpHeaders.CONTENT_ENCODING, ENCODING)
        .post(Entity.text(QUESTION));
    assertEquals(200, response.getStatus());
    assertEquals(ENCODING, response.getHeaders().getFirst(CUSTOM_HEADER));
    // Here, the "Content-Encoding" header can be found.
    assertEquals(ENCODING, response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING));
  }
}

Jersey 试图修复我的内容编码的幕后是否发生了一些魔法?(因为它是一种封闭源编码,所以它不能做到这一点,事实上我必须通过查询网络中另一台服务器上的另一个应用程序来解决.)我什至无法在请求转储中发现Content-Encoding"标头,这就是为什么我怀疑泽西根本不发送标头.

Is there some magic happening behind the curtains where Jersey tries to fix up my content encoding? (What it cannot since its a closed-source encoding which I must as a matter of fact resolve by querying another application on another server in the network.) I cannot even discover the "Content-Encoding" header in the request dump which is why I suspect Jersey to not send the header at all.

我当然可以使用一些X-Content-Encoding"标头,如示例中所示.但是这个解决方案很愚蠢.我已经搜索了各种 CommonPropertiesServerPropertiesClientProperties 常量池,但没有找到配置选项.

I could of course use some "X-Content-Encoding" header, this works as demonstrated in the example. But this solution is just dumb. I already searched the various CommonProperties, ServerProperties, ClientProperties constant pools but I did not find a configuration option.

推荐答案

您看到的问题是因为您有效地用

The problem you see is because you are effectively overwriting the Content-Encoding header with the

.post(Entity.text(QUESTION));

打电话.Entity.text(...) 方法生成实体,其内容数据 Variant 字段设置为:

call. The Entity.text(...) method produces entity with the content data Variant fields set to:

media type = "text/plain";
content language = null;
content encoding = null;

内容编码和语言的这些 null 值依次删除任何先前设置的 Content-EncodingContent-Language 标头.要解决此问题,您需要将内容编码指定为实体的一部分:

These null values of content encoding and language in turn erase any previously set Content-Encoding or Content-Language headers. To fix this, you need to specify the content encoding as part of your entity:

    Response response = target(PATH)
            .request()
            .post(Entity.entity(QUESTION, 
                  new Variant(MediaType.TEXT_PLAIN_TYPE, (String) null, "my-encoding")));

(我同意这种行为有点令人困惑,因为它并不明显.也许我们应该修复 Jersey 以不覆盖带有 null 变量字段值(如果设置)的标题...)

(I agree this behavior is somewhat confusing as it is not obvious. Perhaps we should fix Jersey to not override headers with null variant field values if set...)

这篇关于为什么泽西岛会吞下我的“内容编码"?标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆