16.12. POJO モードで SOAP ヘッダーを取得および設定する方法
POJO は、camel-cxf エンドポイントが Camel エクスチェンジを生成または消費した場合に、データフォーマットが Java オブジェクトのリストであることを意味します。Camel はメッセージボディーをこのモードで POJO として公開しても、camel-cxf は SOAP ヘッダーの読み取りおよび書き込みへのアクセスを提供します。ただし、CXF インターセプターは処理後にヘッダーリストから帯域外 SOAP ヘッダーを削除するため、POJO モードの camel-cxf で利用できるのは帯域外 SOAP ヘッダーのみです。
以下の例は、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_LIST)。ヘッダーの値は、CXF SoapHeader オブジェクト(org.apache.cxf.binding.soap.SoapHeader)の List です。以下のスニペットは InsertResponseOutHeaderProcessor (応答メッセージに新しい SOAP ヘッダーを挿入)です。InsertResponseOutHeaderProcessor と InsertRequestOutHeaderProcessor の両方で SOAP ヘッダーにアクセスする方法は実際には同じです。2 つのプロセッサーの唯一の違いは、挿入された SOAP ヘッダーの方向を設定することです。
InsertResponseOutHeaderProcessor の例は、CxfMessageHeadersRelayTest にあります。
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);
}
}