2
votes

I'm trying to create an inbound gateway for a SOAP service, that accepts SOAP requests like the following:

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Header>
    <RequestHeader xmlns="http://test.com/">
      <SecurityToken>mytoken</SecurityToken>
      <RequestID>1234</RequestID>
    </RequestHeader>
  </S:Header>
  <S:Body>
    <BaseRequest xmlns="http://test.com/">
      <RequestData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:type="BalanceRequest">
        <CustomerID>1234</CustomerID>
      </RequestData>
    </BaseRequest>
  </S:Body>
</S:Envelope>

I want to use JAXB for marshalling/unmarshalling the request/response. I have managed to configure Spring/Spring-integration with the following:

<oxm:jaxb2-marshaller id="soapMarshaller" context-path="com.test" />
<int:channel id="soap-channel"/>
<int-ws:inbound-gateway id="ws-inbound-gateway" 
                        request-channel="soap-channel"
                        marshaller="soapMarshaller"/>
<int:service-activator input-channel="soap-channel">
    <bean class="com.test.SoapServiceActivator"/>
</int:service-activator>

And I have tried to extract the SOAP header and body in the service activator.

@ServiceActivator
public BaseResponse issueResponseFor(BaseRequest body, 
                                     @Headers Map<String, Object> headerMap) {
    return null;
}

BaseRequest is a JAXB annotated class.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "requestData"
})
@XmlRootElement(name = "BaseRequest")
public class BaseRequest {

    @XmlElement(name = "RequestData")
    protected BaseRequestBody requestData;

}

My problem is that in the variable body, I get the body of the SOAP request, but I didn't find anyway to extract the headers of the SOAP request. The headerMap variable holds only the standard Spring-Integration headers (replyChannel, errorChannel, id, timestamp). By headers, I mean the SecurityToken+RequestID, and also the HTTP header with the name of the requested action.

Any idea how to do that ?

1

1 Answers

3
votes

Try to use mapped-request-headers="*".

By default the the DefaultSoapHeaderMapper maps only standard headers. And in this case it is only WebServiceHeaders.SOAP_ACTION

UPDATE

Quoting Omar :-)

Thanks ! The following code is working great :

@Autowired
@Qualifier("soapMarshaller") 
Jaxb2Marshaller marshaller; 

@ServiceActivator 
public BaseResponse issueResponseFor(BaseRequest request,  @Header("RequestHeader") SoapHeaderElement soapHeader) { 
      BaseRequestHeader requestHeader = (BaseRequestHeader) JAXBIntrospector.getValue(marshaller.unmarshal(soapHeader.getSource()));`