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

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

问题描述

以下示例为什么在请求中将我的HTTP标头吞入"Content-Encoding".我正在编写一个需要解码自定义编码格式的应用程序.但是,我永远无法从请求中获取"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));
  }
}

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

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天全站免登陆