骆驼在响应原始呼叫者时丢失 HTTP headers

Camel loosing HTTP headers on response to original caller

我已经创建了一个允许我转发 REST 呼叫的路由。一切进展顺利,除了我无法修改响应的 HTTP headers(实际上我什至无法在响应中保持不变)。

// 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

我注意到两件事:

我不知道 header 你究竟失去了什么,但请注意 Camel HTTP component 有一个 默认 header 过滤器 (因为很多 Camel 组件都有)。

如果您不指定自己的 HeaderFilterStrategy, the default HttpHeaderFilterStrategy,则使用。

此默认筛选以下 headers:

  • content-length
  • content-type
  • 主机
  • cache-control
  • 连接
  • 日期
  • 语用
  • 预告片
  • transfer-encoding
  • 升级
  • 通过
  • 警告
  • 驼色*
  • org.apache.camel*

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

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

实际上,问题出在 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();
  }
}