I am working on spring web services. I need to add some custom elements in the request and response message.which should look like this:
This is probably only half the answer you need but I think you can read the soapheaders by getting the (Saaj)SoapMessage from the messagecontext, like this:
@PayloadRoot(
localPart = "GetHiredCandidatesRequest",
namespace = DEFAULT_NAMESPACE
)
@ResponsePayload
public GetHiredCandidatesResponse getKandidaat (
@RequestPayload GetHiredCandidatesRequest getCandidate,
MessageContext messageContext) {
SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest();
SoapHeader header = request.getSoapHeader();
GetHiredCandidatesResponse response = objectFactory.createGetHiredCandidatesResponse();
response.getCandidate().addAll(
candidateService.getHiredCandidates(
getCandidate.getFrom(),
getCandidate.getTo()
)
);
return response;
}
Since version 2 you can automatically 'add' some objects to your method's signature, like I add the MessageContext
here. I have used this to get the attachments from a soap message for instance. You can probably use other subclasses of AbstractSoapMessage
as well since the the getSoapHeder
method is in that class.
[edit] BTW: Perhaps you can use Interceptors as well since the request / response is provided there. Take a look at the org.springframework.ws.soap.server.endpoint.interceptor package for some default examples. [/edit]
Finally i succeeded in reading the soap header from request and append into response. This is how my end point method looks like now:
@PayloadRoot(localPart = REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
@ResponsePayload
public GetOrderNumberResponse processOrderNumberRequest(
@RequestPayload GetOrderNumberRequest request,
MessageContext messageContext) throws Exception {
logger.info("Request Received");
// read SOAP Header from request and append in response
SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext
.getRequest();
SoapHeader reqheader = soapRequest.getSoapHeader();
SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext
.getResponse();
SoapHeader respheader = soapResponse.getSoapHeader();
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Iterator<SoapHeaderElement> itr = reqheader.examineAllHeaderElements();
while (itr.hasNext()) {
SoapHeaderElement ele = itr.next();
transformer.transform(ele.getSource(), respheader.getResult());
}
// process the request PayLoad
GetOrderNumberResponse response = null;
try {
response = getOrderNumberService.executeRequest(request);
} catch (CannotCreateTransactionException e) {
logger.error(ErrorConstants.ERROR_E17);
throw new ServiceException(ErrorConstants.ERROR_E17);
}
logger.info("Response Sent");
return response;
}
Much easier if you using jaxb marshaller. And this working if body and header has different namespace.
import org.springframework.ws.soap.server.endpoint.annotation.SoapHeader;//@SoapHeader
@PayloadRoot(namespace = "http://body.namespace", localPart = "getRequest")
@ResponsePayload
public JAXBElement<GetResponse> getSomething(@RequestPayload JAXBElement<GetRequest> request
//SOAPHeader is element name from header.xsd: <xsd:element name="SOAPHeader" type="tns:HeaderType"/>
,@SoapHeader(value = "{http://namespace.x.com/Header/}SOAPHeader") SoapHeaderElement headerElem
,MessageContext messageContext) {
try {
JAXBContext context = JAXBContext.newInstance(HeaderType.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
//get soapheader from request
DOMSource headerSource = (DOMSource) headerElem.getSource();
//unmarshall to HeaderType object, headerSource.getNode() because header has different namespace from body namespace
//HeaderType is an xml annotated class
HeaderType headerRequest = ((JAXBElement<HeaderType>) unmarshaller.unmarshal(headerSource.getNode(), HeaderType.class)).getValue();
//get soapheader from response
SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
org.springframework.ws.soap.SoapHeader soapResponseHeader = soapResponse.getSoapHeader();
//marshall headerRequest to response soapheader
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(headerRequest, soapResponseHeader.getResult());
} catch (JAXBException e) {
e.printStackTrace();
}
//create response body message
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<GetResponse> response = objectFactory.createGetResponse(new GetResponse());
response.getValue().setErrorMessage("ok");
return response;
}