17.4.6. 只在 POJO 模式中可用
relayHeaders=true 表示转发标头的意图。给定标头是否转发的实际决定被委派给实施 MessageHeadersRelay 接口的可插拔实例。将查阅 MessageHeadersRelay 的 Concrete 实现,以确定是否需要转发标头。已经有一个 SoapMessageHeadersRelay 的实现,它将自己绑定到众所周知的 SOAP 名称空间。目前只过滤带外标头,当 relayHeaders=true 时,才会转发带中的标头。如果有线上有名称空间未知给运行时的标头,则会使用回退到 DefaultMessageHeadersRelay,它只是允许转发所有标头。
relayHeaders=false 设置指定所有标头 in-band 和 out-band 都应丢弃。
您可以插入自己的 MessageHeadersRelay 实施覆盖,或者在中继列表中添加其他插件。要覆盖预先加载的中继实例,只需确保您的 MessageHeadersRelay 实现服务与您要覆盖的名称空间相同。另请注意,覆盖中继必须作为您查找覆盖的所有命名空间服务,否则路由启动时的其他运行时异常将被抛出,因为这会在命名空间到中继实例映射中引入模糊性。
<cxf:cxfEndpoint ...>
<cxf:properties>
<entry key="org.apache.camel.cxf.message.headers.relays">
<list>
<ref bean="customHeadersRelay"/>
</list>
</entry>
</cxf:properties>
</cxf:cxfEndpoint>
<bean id="customHeadersRelay" class="org.apache.camel.component.cxf.soap.headers.CustomHeadersRelay"/>
查看测试,其中显示了如何进行转发/过滤标头:
-
支持
POJO和PAYLOAD模式。在POJO模式中,只有带外消息标头才能过滤,因为没有 CXF 从标头列表中处理并删除在带中的标头列表中。in-band 标头合并到 POJO 模式的MessageContentList中。camel-cxf组件会导致尝试从MessageContentList中删除带外标头。如果需要过滤 in-band 标头,请使用PAYLOAD模式或插件(pretty simple) CXF 拦截器/JAXWS Handler 到 CXF 端点。 -
Message Header Relay 机制已合并到
CxfHeaderFilterStrategy中。relayHeaders选项、其语义和默认值保持不变,但它是CxfHeaderFilterStrategy的属性。以下是配置它的示例:
@Bean
public HeaderFilterStrategy dropAllMessageHeadersStrategy() {
CxfHeaderFilterStrategy headerFilterStrategy = new CxfHeaderFilterStrategy();
headerFilterStrategy.setRelayHeaders(false);
return headerFilterStrategy;
}
然后,您的端点可以引用 CxfHeaderFilterStrategy。
@Bean
public CxfEndpoint routerNoRelayEndpoint(HeaderFilterStrategy dropAllMessageHeadersStrategy) {
CxfSpringEndpoint cxfEndpoint = new CxfSpringEndpoint();
cxfEndpoint.setServiceClass(org.apache.camel.component.cxf.soap.headers.HeaderTester.class);
cxfEndpoint.setAddress("/CxfMessageHeadersRelayTest/HeaderService/routerNoRelayEndpoint");
cxfEndpoint.setWsdlURL("soap_header.wsdl");
cxfEndpoint.setEndpointNameAsQName(
QName.valueOf("{http://apache.org/camel/component/cxf/soap/headers}SoapPortNoRelay"));
cxfEndpoint.setServiceNameAsQName(SERVICENAME);
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("dataFormat", "PAYLOAD");
cxfEndpoint.setProperties(properties);
cxfEndpoint.setHeaderFilterStrategy(dropAllMessageHeadersStrategy);
return cxfEndpoint;
}
@Bean
public CxfEndpoint serviceNoRelayEndpoint(HeaderFilterStrategy dropAllMessageHeadersStrategy) {
CxfSpringEndpoint cxfEndpoint = new CxfSpringEndpoint();
cxfEndpoint.setServiceClass(org.apache.camel.component.cxf.soap.headers.HeaderTester.class);
cxfEndpoint.setAddress("http://localhost:" + port + "/services/CxfMessageHeadersRelayTest/HeaderService/routerNoRelayEndpointBackend");
cxfEndpoint.setWsdlURL("soap_header.wsdl");
cxfEndpoint.setEndpointNameAsQName(
QName.valueOf("{http://apache.org/camel/component/cxf/soap/headers}SoapPortNoRelay"));
cxfEndpoint.setServiceNameAsQName(SERVICENAME);
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("dataFormat", "PAYLOAD");
cxfEndpoint.setProperties(properties);
cxfEndpoint.setHeaderFilterStrategy(dropAllMessageHeadersStrategy);
return cxfEndpoint;
}
然后配置路由,如下所示:
rom("cxf:bean:routerNoRelayEndpoint")
.to("cxf:bean:serviceNoRelayEndpoint");
-
MessageHeadersRelay接口已稍有变化,并被重命名为MessageHeaderFilter。它是CxfHeaderFilterStrategy的属性。以下是配置用户定义的消息标头过滤器的示例:
@Bean
public HeaderFilterStrategy customMessageFilterStrategy() {
CxfHeaderFilterStrategy headerFilterStrategy = new CxfHeaderFilterStrategy();
List<MessageHeaderFilter> headerFilterList = new ArrayList<MessageHeaderFilter>();
headerFilterList.add(new SoapMessageHeaderFilter());
headerFilterList.add(new CustomHeaderFilter());
headerFilterStrategy.setMessageHeaderFilters(headerFilterList);
return headerFilterStrategy;
}
-
除了
relayHeaders外,也可以在CxfHeaderFilterStrategy中配置以下属性。
| 名称 | 必填 | 描述 |
|---|---|---|
|
| 否 |
所有消息标头都将由 Message Header Filters Type: |
|
| 否 |
所有消息标头都会被传播(不通过 Message Header Filters) 类型 : |
|
| 否 |
如果激活命名空间中的两个过滤器重叠,则属性控制应如何处理它。如果值为 |