骆驼在响应原始呼叫者时丢失 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
我注意到两件事:
- 如果我在处理器中添加 body,那么 body 会出现在响应中,
- 如果我移除处理器,“原始响应”中的 headers 也不存在。
我不知道 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();
}
}
我已经创建了一个允许我转发 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
我注意到两件事:
- 如果我在处理器中添加 body,那么 body 会出现在响应中,
- 如果我移除处理器,“原始响应”中的 headers 也不存在。
我不知道 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();
}
}