29.13. 如何在 POJO 模式中获取和设置 SOAP 标头
POJO 表示,当 camel-cxf 端点生成或使用 Camel 交换时,数据格式是 Java 对象列表。尽管 Camel 在此模式中将消息正文公开为 POJO,但 camel-cxf 仍然提供对读取和写入 SOAP 标头的访问。但是,由于 CXF 拦截器在处理后从标头列表中删除带外 SOAP 标头,因此只有带外 SOAP 标头可用于 POJO 模式 camel-cxf。
以下示例演示了如何获取/设置 SOAP 标头。假设我们有一个路由,它从一个 Camel-cxf 端点转发到另一个端点。也就是说,SOAP Client
from("cxf:bean:routerRelayEndpointWithInsertion")
.process(new InsertRequestOutHeaderProcessor())
.to("cxf:bean:serviceRelayEndpointWithInsertion")
.process(new InsertResponseOutHeaderProcessor());
Bean routerRelayEndpointWithInsertion 和 serviceRelayEndpointWithInsertion 定义如下:
@Bean
public CxfEndpoint routerRelayEndpointWithInsertion() {
CxfSpringEndpoint cxfEndpoint = new CxfSpringEndpoint();
cxfEndpoint.setServiceClass(org.apache.camel.component.cxf.soap.headers.HeaderTester.class);
cxfEndpoint.setAddress("/CxfMessageHeadersRelayTest/HeaderService/routerRelayEndpointWithInsertion");
cxfEndpoint.setWsdlURL("soap_header.wsdl");
cxfEndpoint.setEndpointNameAsQName(
QName.valueOf("{http://apache.org/camel/component/cxf/soap/headers}SoapPortRelayWithInsertion"));
cxfEndpoint.setServiceNameAsQName(SERVICENAME);
cxfEndpoint.getFeatures().add(new LoggingFeature());
return cxfEndpoint;
}
@Bean
public CxfEndpoint serviceRelayEndpointWithInsertion() {
CxfSpringEndpoint cxfEndpoint = new CxfSpringEndpoint();
cxfEndpoint.setServiceClass(org.apache.camel.component.cxf.soap.headers.HeaderTester.class);
cxfEndpoint.setAddress("http://localhost:" + port + "/services/CxfMessageHeadersRelayTest/HeaderService/routerRelayEndpointWithInsertionBackend");
cxfEndpoint.setWsdlURL("soap_header.wsdl");
cxfEndpoint.setEndpointNameAsQName(
QName.valueOf("{http://apache.org/camel/component/cxf/soap/headers}SoapPortRelayWithInsertion"));
cxfEndpoint.setServiceNameAsQName(SERVICENAME);
cxfEndpoint.getFeatures().add(new LoggingFeature());
return cxfEndpoint;
}
SOAP 标头被传播到 Camel 消息标头。Camel 消息标头名称是 "org.apache.cxf.headers.Header.list",它是 CXF 中定义的常量(org.apache.cxf.headers.Header.Header.HEADER_LIST)。标头值是 CXF SoapHeader 对象列表(org.apache.cxf.binding.soap.SoapHeader)。以下片段是 InsertResponseOutHeaderProcessor (它会在响应消息中插入一个新的 SOAP 标头)。在 InsertResponseOutHeaderProcessor 和 InsertRequestOutHeaderProcessor 中访问 SOAP 标头的方式实际相同。两个处理器之间的唯一区别是设置插入 SOAP 标头的方向。
您可以在 CxfMessageHeadersRelayTest 中找到 InsertResponseOutHeaderProcessor 示例:
public static class InsertResponseOutHeaderProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
List<SoapHeader> soapHeaders = CastUtils.cast((List<?>)exchange.getIn().getHeader(Header.HEADER_LIST));
// Insert a new header
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><outofbandHeader "
+ "xmlns=\"http://cxf.apache.org/outofband/Header\" hdrAttribute=\"testHdrAttribute\" "
+ "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" soap:mustUnderstand=\"1\">"
+ "<name>New_testOobHeader</name><value>New_testOobHeaderValue</value></outofbandHeader>";
SoapHeader newHeader = new SoapHeader(soapHeaders.get(0).getName(),
DOMUtils.readXml(new StringReader(xml)).getDocumentElement());
// make sure direction is OUT since it is a response message.
newHeader.setDirection(Direction.DIRECTION_OUT);
//newHeader.setMustUnderstand(false);
soapHeaders.add(newHeader);
}
}