【问题标题】:Remove headers from openfeign request set by default http client从默认http客户端设置的openfeign请求中删除标头
【发布时间】:2020-01-15 03:40:26
【问题描述】:

我正在调用一个 API,它将某些 HttpHeaders 列入黑名单,包括 Content-Length,这似乎是由 spring-openfeign 下的 HttpClient 预设的。 要正确接收 API 响应,我需要删除 Content-Length 标头。

已尝试以下解决方法:

  • 我尝试使用可用的 Feign 注释 @Headers@RequestHeaders 将标头设置为 null 或空字符串
  • 我实现了一个RequestInterceptor,它创建了可用(不可变)标头映射的副本,删除了列入黑名单的标头并将映射设置为requestTemplate.headers(newHeaders)。但是只能添加新的标头,而不能修改可用的标头(似乎真的是不可变的;))
  • 我研究了覆盖使用的 HttpClient,但直到现在才成功。

遇到的错误/问题:

我正在调用的 API 根据其标头架构验证返回 400。

代码:

如果需要任何 code-sn-ps,我很乐意提供它们,但对我来说,这个问题似乎与任何代码问题无关,因为我没有遇到任何异常。

提前致谢!!

【问题讨论】:

    标签: java spring-boot spring-cloud-feign feign


    【解决方案1】:

    如果存在请求正文,feign-httpclient 中包含的 Apache Http 客户端将始终设置内容长度标头。解决此问题的一种方法是直接配置 Apache 客户端并通过构建器将其提供给 Feign:

    此自定义客户端可以应用 Apache Http Client 拦截器,允许您在请求离开 Feign 之后和 Apache 发送之前修改请求。查看their javadoc 了解更多信息。

    public class Example {
      public static void main(String[] args) {
        HttpClient httpClient = HttpClients.custom.build();
        GitHub github = Feign.builder()
                         .client(new ApacheHttpClient(httpClient))
                         .target(GitHub.class, "https://api.github.com");
      }
    }
    

    【讨论】:

    • 我也试过那个。不幸的是,Content-Length 也将由 ApacheClient 添加。同时,我相信当有请求主体时,它总是被添加到请求中。老实说,对我来说,这是所有请求的有效行为,我会责怪生产者 API 没有按照标准开发......
    【解决方案2】:

    FeignClient 会在请求头中预设 Content_Length。在 keep-alive 连接模式下,必须设置 Content-Length 或 Transfer-Encoding 标头字段以指示消息体的存在,因此您可以设置 Transfer-Encoding=chunked 并且 Content-Length 将被服务器端忽略。

    可以参考rfc7230#section-3.3.1

    “请求中存在消息体由
    Content-Length 或 Transfer-Encoding 标头字段。请求留言
    框架独立于方法语义,即使方法确实如此
    没有为消息体定义任何用途。”

    “为了保持持久性,连接上的所有消息都需要 有一个自定义的消息长度(即,一个不是由 连接关闭),如第 3.3 节所述。一台服务器 必须阅读整个请求消息体或关闭连接 发送其响应后,因为否则剩余的数据 持久连接会被误解为下一个请求。 同样,客户端必须读取整个响应消息体,如果它 打算为后续请求重用相同的连接。”

    here,你可以阅读:

    “所有接收实体的 HTTP/1.1 应用程序必须接受 “分块”传输编码(第 3.6 节),因此允许这种机制 用于无法确定消息长度时的消息 提前。

    消息不得同时包含 Content-Length 标头字段和 非身份传输编码。如果消息确实包含非 身份传输编码,必须忽略 Content-Length。

    当在消息正文中给出 Content-Length 时 允许,其字段值必须与 消息体。 HTTP/1.1 用户代理必须通知用户 接收并检测到无效长度。”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-13
      • 2020-03-09
      • 1970-01-01
      • 2018-07-16
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      • 2021-02-05
      相关资源
      最近更新 更多