25.13. 如何在 POJO 模式中获取和设置 SOAP 标头
POJO 表示当 camel-cxf 端点生成或消耗 Camel 交换时,数据格式是 Java 对象的"列表"。虽然 Camel 在此模式下公开消息正文作为 POJO,但 camel-cxf 仍提供对读取和写入 SOAP 标头的访问。但是,由于 CXF 拦截器在处理后从标头列表中删除带中的 SOAP 标头,因此只有 POJO 模式中的 camel-cxf 使用带外 SOAP 标头。
以下示例演示了如何获取/设置 SOAP 标头。假设我们有一个路由,它从一个 Camel-cxf 端点转发到另一个 Camel-cxf 端点。也就是说,SOA 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 消息标头传播。Camel 消息标头名称为 "org.apache.cxf.headers.Header.list",它是 CXF (org.apache.cxf.headers.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);
}
}