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:
<soapenv:Envelope>
<soapenv:Header>
<tid:SplsTID>
<tid:Trantype>123</tid:Trantype>
<tid:Tranver>234</tid:Tranver>
</tid:SplsTID>
</soapenv:Header>
<soapenv:Body>
<get:GetOrderNumberRequest LoggingLevel="REGULAR" MonitorFlag="Y">
<get:Header>
<get:TransactionId>111</get:TransactionId>
<get:SourceSystemId>SOMS</get:SourceSystemId>
<get:DateTime>2011-11-11T11:11:11</get:DateTime>
</get:Header>
<get:Body>
<get:StaplesOrderNumber RangeFlag="N" ReleaseFlag="N">
<get:OrderNumber Count="1" End="11" Start="9"/>
</get:StaplesOrderNumber>
</get:Body>
</get:GetOrderNumberRequest>
</soapenv:Body>
</soapenv:Envelope>
i am able to append <tid:SplsTID>
under <soapenv:Header>
in request by modifying the WSDL file. which looks like this:
<wsdl:message name="GetOrderNumberRequest">
<wsdl:part element="tns:GetOrderNumberRequest" name="GetOrderNumberRequest">
</wsdl:part>
<wsdl:part element="sch1:SplsTID" name="SplsTID">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetOrderNumberResponse">
<wsdl:part element="tns:GetOrderNumberResponse" name="GetOrderNumberResponse">
</wsdl:part>
<wsdl:part element="sch1:SplsTID" name="SplsTID">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="ONAS">
<wsdl:operation name="GetOrderNumber">
<wsdl:input message="tns:GetOrderNumberRequest" name="GetOrderNumberRequest">
</wsdl:input>
<wsdl:output message="tns:GetOrderNumberResponse" name="GetOrderNumberResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
The problem is, i want to read <tid:SplsTID>
part from the request and wanted to append it under soap header part of the response, which is not happening. i am using annotation based end point. what is the code which will read the soap header and will append the same in the response.
currently my end point class is:
@Endpoint
public class OrderNumberServiceEndPoint {
public static final String NAMESPACE_URI = "http://schemas.staples.com/onas/getOrderNumber";
/**
* The local name of the expected request.
*/
public static final String REQUEST_LOCAL_NAME = "GetOrderNumberRequest";
/**
* The local name of the created response.
*/
public static final String RESPONSE_LOCAL_NAME = "GetOrderNumberResponse";
private GetOrderNumberService getOrderNumberService;
public void setGetOrderNumberService(
GetOrderNumberService getOrderNumberService) {
this.getOrderNumberService = getOrderNumberService;
}
@PayloadRoot(localPart = REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
public GetOrderNumberResponse processOrderNumberRequest(
GetOrderNumberRequest request) throws Exception {
GetOrderNumberResponse response = null;
try{
response = getOrderNumberService.executeRequest(request);
}catch(CannotCreateTransactionException e){
logger.error(ErrorConstants.ERROR_E17);
throw new ServiceException(ErrorConstants.ERROR_E17);
}
return response;
}
}
Let me know if more details are required. Any help would be appreciated.
SOAPHeader header = message. getSOAPHeader(); QName headerName = new QName("http://ws-i.org/schemas/conformanceClaim/", "Claim", "wsi"); SOAPHeaderElement headerElement = header. addHeaderElement(headerName); headerElement. addAttribute(new QName("conformsTo"), "http://ws-i.org/profiles/basic/1.1/");
HTTP headers are used for HTTP Basic/Digest authentication. SOAP headers are used for WS-Security style authentication. Unfortunately, the process of applying WS-Security differs from SOAP stack to SOAP stack; you'll have to consult the documentation of whichever stack you're using.
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;
}
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]
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