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());
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; }
@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); } }
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);
}
}