How to get and set SOAP headers in POJO mode - 6.3

Talend ESB Mediation Developer Guide

EnrichVersion
6.3
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Design and Development
EnrichPlatform
Talend ESB

POJO means that the data format is a "list of Java objects" when the Camel-cxf endpoint produces or consumes Camel exchanges. Even though Camel expose message body as POJOs in this mode, Camel-cxf still provides access to read and write SOAP headers. However, since CXF interceptors remove in-band SOAP headers from Header list after they have been processed, only out-of-band SOAP headers are available to Camel-cxf in POJO mode.

The following example illustrate how to get/set SOAP headers. Suppose we have a route that forwards from one Camel-cxf endpoint to another. That is, SOAP Client -> Camel -> CXF service. We can attach two processors to obtain/insert SOAP headers at (1) before request goes out to the CXF service and (2) before response comes back to the SOAP Client. Processor (1) and (2) in this example are InsertRequestOutHeaderProcessor and InsertResponseOutHeaderProcessor. Our route looks like this:

<route>
   <from uri="cxf:bean:routerRelayEndpointWithInsertion"/>
   <process ref="InsertRequestOutHeaderProcessor" />
   <to uri="cxf:bean:serviceRelayEndpointWithInsertion"/>
   <process ref="InsertResponseOutHeaderProcessor" />
</route>     

In 2.x SOAP headers are propagated to and from Camel Message headers. The Camel message header name is "org.apache.cxf.headers.Header.list" which is a constant defined in CXF (org.apache.cxf.headers.Header.HEADER_LIST). The header value is a List of CXF SoapHeader objects (org.apache.cxf.binding.soap.SoapHeader). The following snippet is the InsertResponseOutHeaderProcessor (that inserts a new SOAP header in the response message). The way to access SOAP headers in both InsertResponseOutHeaderProcessor and InsertRequestOutHeaderProcessor is the same. The only difference between the two processors is setting the direction of the inserted SOAP header.

public static class InsertResponseOutHeaderProcessor implements Processor {

   @SuppressWarnings("unchecked")
   public void process(Exchange exchange) throws Exception {
      List<SoapHeader> soapHeaders = 
               (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);
    }  
}

In 1.x SOAP headers are not propagated to and from Camel Message headers. Users have to go deeper into CXF APIs to access SOAP headers. Also, accessing the SOAP headers in a request message is slight different than in a response message. The InsertRequestOutHeaderProcessor and InsertResponseOutHeaderProcessor are as follows:

public static class InsertRequestOutHeaderProcessor implements Processor {

   public void process(Exchange exchange) throws Exception {
      CxfMessage message = exchange.getIn().getBody(CxfMessage.class);
      Message cxf = message.getMessage();
      List<SoapHeader> soapHeaders = (List)cxf.get(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 IN since it is a request message.
      newHeader.setDirection(Direction.DIRECTION_IN);
      //newHeader.setMustUnderstand(false);
      soapHeaders.add(newHeader);       
   }
}

public static class InsertResponseOutHeaderProcessor 
   implements Processor {

   public void process(Exchange exchange) throws Exception {
      CxfMessage message = exchange.getIn().getBody(CxfMessage.class);
      Map responseContext = 
         (Map)message.getMessage().get(Client.RESPONSE_CONTEXT);
      List<SoapHeader> soapHeaders = 
         (List)responseContext.get(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);
   }
}