We're using spring-ws 2.2 on our application to consume web services. We've been happily doing this for quite some time and everything is working fine, except that now I need to access the SOAP header in the response and I just can't find a way to do this.
We are using a WebServiceTemplate (from springs-ws) configured with a Jaxb2Marshaller. The jaxb files are generated from the wsdl using xjc. The header element in my responses look something like this:
<soapenv:Header>
<v1:ResponseHeader status="OK">
<v1:description>test</v1:description>
</v1:ResponseHeader>
</soapenv:Header>
In my java class, the code that parses the response looks like this (I've stripped some irrelevant code):
public CalculationData getValues(Integer id) throws IntegrationException {
WebServiceMessageCallback callback = createCallback(soapAction);
GetValuesRequest request = toGetValues(id);
GetValuesResponse response = null;
try {
response = (GetValuesResponse) webServiceTemplate.marshalSendAndReceive(request, callback);
} catch (SOAPFaultException fault) {
log.error("Soap fault occurred during getValues " + id);
throw new IntegrationException(fault);
}
CalculationData data = fromGetValues(response);
return data;
}
Please help me find a solution for extracting the information from the SOAP header out of the response. I must be able to parse the status code which is sent as an attribute.
By the way. I also have a ResponseHeader.java jaxb class which has been generated from the schemas.
Update from final changes:
This is how my handleResponse method looks like after inlining a ClientInterceptor implementation:
@Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
SoapMessage message = (SoapMessage) messageContext.getResponse();
Iterator<SoapHeaderElement> responseHeaderElements =
message.getSoapHeader().examineAllHeaderElements();
SoapHeaderElement header = null;
if (responseHeaderElements.hasNext()) {
header = responseHeaderElements.next();
} else {
log.error("Error! No ResponseHeader found in response.");
return false;
}
String responseCode = header.getAttributeValue(new QName(STATUS_QNAME));
responseMsg.put(RESPONSE_MSG_KEY, responseCode);
return true;
}
I tried getting the ResponseHeader element by QName, but that did not seem to work for some reason. However, I only expect to get one element in the soap header anyhow, is this will work fine.
For this use case, the best solution is to use a custom WebServiceMessageExtractor, as described here:
http://veithen.github.io/2015/01/03/spring-ws-extracting-soap-headers-from-responses.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With