【问题标题】:Camel loosing HTTP headers on response to original caller骆驼在响应原始调用者时丢失 HTTP 标头
【发布时间】:2021-10-30 00:37:34
【问题描述】:

我创建了一个路由来允许我转发 REST 调用。一切都很顺利,除了我无法修改响应的 HTTP 标头(实际上我什至无法让它们在响应中保持不变)。

// My processor
private void remplacerLiensDansHeader(final Exchange exchange, final String rootUrlPivotJoram, final String rootUrlRemplacement) {
    // That is OK, I get the values just fine
    ArrayList<String> oldLinks = exchange.getIn().getHeader(HEADER_LINK, ArrayList.class);

    // This is also OK
    final List<String> newLinks = anciensLiens.stream().map(lien -> lien.replace(rootUrlPivotJoram, rootUrlRemplacement)).collect(toList());

    // No error, but apparently doesn't work
    exchange.getMessage().setHeader(HEADER_LINK, newLinks);
    exchange.getMessage().setHeader("test", "test");
}

// Route configuration
@Override
public void configure() throws Exception {
    this.from(RestRouteBuilder.endPoint(createProducerJoramConfiguration))
        .setExchangePattern(InOut)
        .removeHeader(Exchange.HTTP_URI)
        .toD(createProducerJoramConfiguration.getUrlDestination())
        .setHeader("test", () -> "test") // that doesn't work either
        .process(createProducerJoramConfiguration.getProcessor()); // this is the processor with the code above
}

这是我得到的回复(注意回复码是200,我觉得很奇怪,原来是201

curl -v -XPost --user "xxx:yyyy" http://localhost:10015/zzzz/webservices/xxxxx
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 10015 (#0)
* Server auth using Basic with user 'xxx'
> Post /zzzzz/webservices/eeee HTTP/1.1
> Host: localhost:10015
> Authorization: Basic pppppppppppppppppp==
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200
< Date: Tue, 31 Aug 2021 11:17:49 GMT
< Content-Type: application/octet-stream
< Content-Length: 0
<
* Connection #0 to host localhost left intact

我注意到了两件事:

  • 如果我在处理器中添加一个主体,那么主体就会出现在响应中,
  • 如果我移除处理器,“原始响应”中的标头也不存在。

【问题讨论】:

    标签: java routes http-headers apache-camel esb


    【解决方案1】:

    我不知道您究竟丢失了哪些标头,但请注意 Camel HTTP component 有一个默认标头过滤器(很多 Camel 组件都有)。

    如果您不指定自己的HeaderFilterStrategy,则使用默认的HttpHeaderFilterStrategy

    此默认过滤器会过滤以下标题:

    • 内容长度
    • 内容类型
    • 主持人
    • 缓存控制
    • 连接
    • 日期
    • 编译指示
    • 预告片
    • 传输编码
    • 升级
    • 通过
    • 警告
    • 骆驼*
    • org.apache.camel*

    使用这个过滤器,Camel 希望避免旧的 HTTP 标头仍然存在于传出请求中(可能带有错误的数据)。

    Camel 标头的过滤只是为了删除与 HTTP 无关的 Camel 特定内容。

    【讨论】:

    • 感谢您不幸地回答我丢失了一个与上述任何一项无关的自定义标题。
    【解决方案2】:

    其实问题出在 cxfrs 组件上。

    我们设法在这里找到答案:请参阅:Response to REST client from Camel CXFRS route?

    这是最终的解决方案。

    感谢所有看过或回答的人,我希望这对其他人有帮助。

    public class ModificationHeaderLinkProcessor implements Processor {
    
      private static final String HEADER_LINK = "Link";
    
      @Override
      public void process(final Exchange exchange) {
        List<String> newLinks= getNewLinks(exchange, oldUrl, newUrl);
        ResponseBuilder builder = createHttpResponse(exchange);
        builder.header(HEADER_LINK, newLinks);
        exchange.getIn().setBody(builder.build());
      }
    
      private List<String> getNewLinks(final Exchange exchange, final String oldUrl, final String newUrl) {
        ArrayList<String> oldLinks= exchange.getIn().getHeader(HEADER_LINK, ArrayList.class);
        return oldLinks.stream().map(link-> link.replace(oldUrl, newUrl)).collect(toList());
      }
    
      private ResponseBuilder createHttpResponse(final Exchange exchange) {
        ResponseBuilder builder = Response.status(getHttpStatusCode(exchange))
                                          .entity(exchange.getIn().getBody());
        clearUselessHeader(exchange);
        exchange.getIn().getHeaders().forEach(builder::header);
        return builder;
      }
    
      private void clearUselessHeader(final Exchange exchange) {
        exchange.getIn().removeHeader(HEADER_LINK);
        exchange.getIn().removeHeaders("Camel*");
      }
    
      private Integer getHttpStatusCode(final Exchange exchange) {
        return exchange.getIn().getHeader(exchange.HTTP_RESPONSE_CODE, Integer.class);
      }
    
      private final String getPropertiesValue(CamelContext camelContext, String key) {
        return camelContext.getPropertiesComponent().resolveProperty(key).orElseThrow();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-11
      • 2017-03-10
      • 2023-04-05
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      相关资源
      最近更新 更多