How to retrieve From/Address value in SOAP header (in Java/SpringBoot) - java

I'm trying to create a Spring Boot SOAP application using this tutorial: https://www.baeldung.com/spring-boot-soap-web-service Everything works like a charm so far.
Task: I'd like to access the SOAP header.
This is what I've done so far:
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
#ResponsePayload
public GetCountryResponse getCountry(#RequestPayload GetCountryRequest request) {
[..]
}
I can just extend this with MessageContext:
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
#ResponsePayload
public GetCountryResponse getCountry(#RequestPayload GetCountryRequest request, MessageContext messageContext) {
[..]
}
This MessageContext plus a little util method fooBar is supposed to access the SOAP header:
protected static String fooBar(final MessageContext messageContext) {
SoapHeader soapHeader = ((SoapMessage) messageContext.getRequest()).getSoapHeader();
[...]
}
So far so good. This is what my SOAP message looks like:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
[...]
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soap:Header>
[...]
<wsa:From>
<wsa:Address>http://from-endpoint</wsa:Address>
</wsa:From>
[...]
</soap:Header>
<soap:Body>
[...]
</soap:Body>
</soap:Envelope>
I would like to get the address in <From><Address>: http://from-endpoint .. but now it starts to get awkward..
protected static String fooBar(final MessageContext messageContext) {
SoapHeader soapHeader = ((SoapMessage) messageContext.getRequest()).getSoapHeader();
Iterator<SoapHeaderElement> soapHeaderElementIterator = soapHeader.examineAllHeaderElements();
while (soapHeaderElementIterator.hasNext()) {
SoapHeaderElement soapHeaderElement = soapHeaderElementIterator.next();
if (soapHeaderElement.getName().getLocalPart().equals("From")) {
[...]
This works as expected, but this SoapHeaderElement is type org.springframework.ws.soap.SoapHeaderElement which gives me no options to access further child elements.
What am I doing wrong here?
...
...
...
✅ SOLUTION has been found - see comments

Thanks to help of M. Deinum I've found a solution:
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
#ResponsePayload
public GetCountryResponse getCountry(#RequestPayload GetCountryRequest request, MessageContext messageContext) {
Addressing10 addressing10 = new Addressing10();
MessageAddressingProperties messageAddressingProperties = addressing10.getMessageAddressingProperties((SoapMessage) messageContext.getRequest());
URI address = messageAddressingProperties.getFrom().getAddress();
}

Related

In SpringBoot web service endpoint, how do I access http headers?

I have a class annotated with #Endpoint and a handler method
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getWeatherRequest")
#SoapAction("http://foo/domain/getWeatherRequest")
#ResponsePayload
public GetWeatherResponse getWeatherRequest(#RequestPayload GetWeatherRequest request) {
// I want to get HTTP header (Not SOAP Header) here
}
Try using the #RequestHeader annotation
#SoapAction("http://foo/domain/getWeatherRequest")
#ResponsePayload
public GetWeatherResponse getWeatherRequest(#RequestPayload GetWeatherRequest request,
#RequestHeader("header-name") String header) {
}
You can use RequestHeader annotation in your method to access http headers, you can specify whether header is mandatory or optional using required attribute
#RequestHeader(value = "ConfigId", required = true) String configId

The value of the HTTP header ' SOAPAction ' was not recognized by the server

When I send a SOAP request to the server it returns following error, though I send similar request using SoapUI and that works. It seems I need to change my SOAP request to the one that I am sending using SoapUI. WSDL is here.
[ truncated ] System.Web.Services.Protocols.SoapException : The value of the
HTTP header ' SOAPAction ' was not recognized by the server . \ r \ n at
System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest ( )
\ r \ n at System.Web.Servic
I am sending following request using Java
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:SearchFlights xmlns:ns2="ElysArres.API">
<ns2:SoapMessage>
<ns2:Username>Test</ns2:Username>
<ns2:Password>TestPassword</ns2:Password>
<ns2:LanguageCode>EN</ns2:LanguageCode>
<ns2:Request>
<ns2:Departure>ONT</ns2:Departure>
<ns2:Destination>EWR</ns2:Destination>
<ns2:DepartureDate>2016-01-20</ns2:DepartureDate>
<ns2:ReturnDate>2016-01-28</ns2:ReturnDate>
<ns2:NumADT>1</ns2:NumADT>
<ns2:NumINF>0</ns2:NumINF>
<ns2:NumCHD>0</ns2:NumCHD>
<ns2:CurrencyCode>EUR</ns2:CurrencyCode>
<ns2:WaitForResult>true</ns2:WaitForResult>
<ns2:NearbyDepartures>true</ns2:NearbyDepartures>
<ns2:NearbyDestinations>true</ns2:NearbyDestinations>
<ns2:RROnly>false</ns2:RROnly>
<ns2:MetaSearch>false</ns2:MetaSearch>
</ns2:Request>
</ns2:SoapMessage>
</ns2:SearchFlights>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I can send following request using SoapUI and it works
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:els="ElsyArres.API">
<soap:Header/>
<soap:Body>
<els:SearchFlights>
<els:SoapMessage>
<els:Username>Test</els:Username>
<els:Password>TestPassword</els:Password>
<els:LanguageCode>EN</els:LanguageCode>
<els:Request>
<els:Departure>ONT</els:Departure>
<els:Destination>EWR</els:Destination>
<els:DepartureDate>2016-01-20</els:DepartureDate>
<els:ReturnDate>2016-01-28</els:ReturnDate>
<els:NumADT>1</els:NumADT>
<els:NumINF>0</els:NumINF>
<els:NumCHD>0</els:NumCHD>
<els:CurrencyCode>EUR</els:CurrencyCode>
<els:WaitForResult>true</els:WaitForResult>
<els:NearbyDepartures>true</els:NearbyDepartures>
<els:NearbyDestinations>true</els:NearbyDestinations>
<els:RROnly>false</els:RROnly>
<els:MetaSearch>false</els:MetaSearch>
</els:Request>
</els:SoapMessage>
</els:SearchFlights>
</soap:Body>
</soap:Envelope>
I am not sure how to make the request that I am creating with Java same as what I am sending with SoapUI.
Code
SearchFlights
#XmlRootElement(name = "SearchFlights")
#XmlAccessorType(XmlAccessType.FIELD)
public class SearchFlights {
#XmlElement(name = "SoapMessage")
private SoapMessage soapMessage;
getter and setter
SoapMessage
#XmlRootElement(name = "SoapMessage")
#XmlAccessorType(XmlAccessType.FIELD)
public class SoapMessage {
#XmlElement(name = "Username")
private String username;
#XmlElement(name = "Password")
private String password;
#XmlElement(name = "LanguageCode")
private String languageCode;
#XmlElement(name = "Request")
private Request request;
getters and setters
Request
#XmlRootElement(name = "Request")
#XmlAccessorType(XmlAccessType.FIELD)
public class Request {
#XmlElement(name = "Departure")
private String departure;
#XmlElement(name = "Destination")
private String destination;
#XmlElement(name = "DepartureDate")
private String departureDate;
#XmlElement(name = "ReturnDate")
private String returnDate;
#XmlElement(name = "NumADT")
private int numADT;
#XmlElement(name = "NumINF")
private int numInf;
#XmlElement(name = "NumCHD")
private int numCHD;
#XmlElement(name = "CurrencyCode")
private String currencyCode;
#XmlElement(name = "WaitForResult")
private boolean waitForResult;
#XmlElement(name = "NearByDepartures")
private boolean nearByDepartures;
#XmlElement(name = "NearByDestinations")
private boolean nearByDestinations;
#XmlElement(name = "RROnly")
private boolean rronly;
#XmlElement(name = "MetaSearch")
private boolean metaSearch;
getters and setters
package-info.java
#XmlSchema(
namespace = "ElsyArres.API",
elementFormDefault = XmlNsForm.QUALIFIED)
package com.myproject.flights.wegolo;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
jaxb.index
SearchFlights
Flight
Flights
Leg
Legs
Outbound
Request
Response
SoapMessage
Code to send request
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPConstants;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
......
// populate searchFlights and other classes to create request
try {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(
MessageFactory.newInstance());
messageFactory.afterPropertiesSet();
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(
messageFactory);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.myproject.flights.wegolo");
marshaller.afterPropertiesSet();
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.afterPropertiesSet();
Response response = (Response) webServiceTemplate
.marshalSendAndReceive(
"http://www5v80.elsyarres.net/service.asmx",
searchFlights);
Response msg = (Response) response;
System.err.println("Wegolo >>>"
+ msg.getFlights().getFlight().size());
} catch (Exception s) {
s.printStackTrace();
}
Update
I removed package-info.java and managed to use the suggested code, but it is still sending the same header.
Response response = (Response) webServiceTemplate
.marshalSendAndReceive(
"http://www5v80.elsyarres.net/service.asmx",
searchFlights,
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message)
{
((SoapMessage)message).setSoapAction("http://www5v80.elsyarres.net/searchFlights");
}
}
);
SOAP Version 1.1 requires a HTTP header in your SOAP request to specify the SOAP action. It's not in the actual XML, it's part of the request (in the HTTP header), so that is why you are not seeing any difference between your SoapUI request xml, and the request you're sending using the WebServiceTemplate. Soap 1.2 allows you to set it as an attribute on the media type, but that is not valid for a 1.1 server. Note that according to the specification, the value you use doesn't have to be resolvable.
SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request.
Usually, it's specified in your WSDL, something like (taken from here):
<soap:operation
soapAction="http://www5v80.elsyarres.net/searchFlights"
style="document" />
If that is not in your WSDL, you can add it by using the action annotation in spring in your webservice endpoint class.
#Endpoint
public class MyFlightEndpoint{
#Action("http://www5v80.elsyarres.net/searchFlights")
public SearchFlights request() {
...
}
}
If it is in your WSDL, you'll want to place that value into your HTTP header on the client side. To do this, you then need to get access to the message on the client side after it's created, but before it's sent in order to add the action header. Spring provides a message callback interface for that, that's described here. What you'll want to do is something like:
Response response = (Response) webServiceTemplate
.marshalSendAndReceive(
"http://www5v80.elsyarres.net/service.asmx",
searchFlights,
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message)
{
((SoapMessage)message).setSoapAction("http://www5v80.elsyarres.net/searchFlights");
}
}
);
There's a discussion on SOAP action headers here, and the point (or lack of a point) for them if you want to know more.
Edit: So looking at the wsdl here:
<soap:operation soapAction="ElsyArres.API/SearchFlights" style="document"/>
you'll want the following action:
ElsyArres.API/searchFlights
Now just update the code to read
((SoapMessage)message).setSoapAction("ElsyArres.API/searchFlights");
and you're good to go!
Edit 2: I also notice the service you're connecting to accepts SOAP 1.2 connections, while you're using SOAP 1.1. You can force your client to use SOAP 1.2 by setting it in your factory.
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
messageFactory.afterPropertiesSet();
It looks like the server uses the same endpoint, so that should be the only change.
I had the same problem, my fix was :
#Configuration
public class SoapConfiguration {
private static final String SOAP_1_2_PROTOCOL= "SOAP 1.2 Protocol";
#Bean
public WebServiceTemplate webServiceTemplate() throws Exception {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(javax.xml.soap.MessageFactory.newInstance(SOAP_1_2_PROTOCOL));
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
messageFactory.afterPropertiesSet();
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(
messageFactory);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("YOUR_WSDL_GENERATED_PATH");
marshaller.afterPropertiesSet();
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.setUnmarshaller(marshaller);
webServiceTemplate.afterPropertiesSet();
return webServiceTemplate;
}
And my SoapService
#Service
#RequiredArgsConstructor
public class SoapDomainBoxService extends WebServiceGatewaySupport {
private final WebServiceTemplate webServiceTemplate;
public void searchFlights(SearchFlights searchFlights) {
String url = "YOUR.URL.asmx";
Response response = (Response) webServiceTemplate.marshalSendAndReceive(url, searchFlights, new SoapActionCallback("ACTION.CALLBACK"));
}
Very important on creation of message factory use
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(javax.xml.soap.MessageFactory.newInstance(SOAP_1_2_PROTOCOL));
Another way to add SOAPAction header when using WebServiceGatewaySupport is to do the following:
getWebServiceTemplate().marshalSendAndReceive(request, new SoapActionCallback("http://httpheader/"));
This is using messageFactory.setSoapVersion(SoapVersion.SOAP_12);

Read SOAP request header with Spring

I am trying to read the SOAP request header from a endpoint in spring this way:
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
#ResponsePayload
public GetCountryResponse getCountry(#RequestPayload GetCountryRequest request, MessageContext context) {
GetCountryResponse response = new GetCountryResponse();
response.setCountry(countryRepository.findCountry(request.getName()));
return response;
}
As you can see I have the MessageContext as a parameter in the handle method of the endpoint and I do the following in order to try to read the SOAP header coming from te request:
SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext.getRequest();
SoapHeader reqheader = soapRequest.getSoapHeader();
while (itr.hasNext()) {
SoapHeaderElement ele = itr.next();
}
Apparently I am getting access to the SOAP header, but at this point I´m not really sure how to read the value of any SOAP header element, I´ve tried different approaches with no success.
For example, if the following SOAP request is coming from the soapUI I want to read the value 123456 from networkCode element:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<ns1:RequestHeader
soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next"
soapenv:mustUnderstand="0"
xmlns:ns1="https://www.google.com/apis/ads/publisher/v201508">
<ns1:networkCode>123456</ns1:networkCode>
<ns1:applicationName>DfpApi-Java-2.1.0-dfp_test</ns1:applicationName>
</ns1:RequestHeader>
</soapenv:Header>
<soapenv:Body>
<getAdUnitsByStatement xmlns="https://www.google.com/apis/ads/publisher/v201508">
<filterStatement>
<query>WHERE parentId IS NULL LIMIT 500</query>
</filterStatement>
</getAdUnitsByStatement>
</soapenv:Body>
</soapenv:Envelope>
Thanks in advance and best reards.
Yoy can you QName to extract data by using necessary tag
SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext
.getRequest();
SoapHeader reqheader = soapRequest.getSoapHeader();
Iterator<SoapHeaderElement> itr = reqheader.examineAllHeaderElements();
while (itr.hasNext()) {
SoapHeaderElement testedElement = itr.next();
if (testedElement.getName()
.equals(new QName("https://www.google.com/apis/ads/publisher/v201508", "networkCode", "ns1"))) {
this.messageId = testedElement.getText();
break;
}
}
In SoapUI using Script assertion,we can do this:
As your request itself contains the Header Details, we can read any element of your Request xml using xpath.
Replace the TeststepName with your TestStepName.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( "TeststepName#Request" )
holder.namespaces["ns1"] = "https://www.google.com/apis/ads/publisher/v201508"
def y = holder["(//ns1:networkCode)"]
log.info "Value of networkCode"+ y
or
assert holder["(//ns1:networkCode)"]=='123456'
please try to get all the Header element from the Your Request like:
SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext.getRequest();
Iterator HeaderList = soapRequest.getEnvelope().getHeader().examineAllHeaderElements();
while (HeaderList.hasNext()) {
SoapHeaderElement HeaderElements = HeaderList.next();
println("\n"+HeaderElements.getName().getLocalPart()+ " - "+HeaderElements.getText());
}
}

How to enable WS-Addresing in client SOAP request for Grails

I have a problem with WS-Addresing in SOAP header. I succesfully imported classes from xsd file with configuration, but server require WS-Addressing attributes in soap header("wsa:action", "wsa:to"). Unfortunettly client service dont inject these attributes and server return http code 400 "Bad Request".
How can I automatically inject a proper SOAP header for requests?
I tried with #Addressing(enabled=true, required=true) annotation, but header was wrong for webservice
Configuration in Config.groovy
Service endpoint: https://wyszukiwarkaregontest.stat.gov.pl/wsBIR/UslugaBIRzewnPubl.svc
Main xsd file: https://wyszukiwarkaregontest.stat.gov.pl/wsBIR/wsdl/UslugaBIRzewnPubl.xsd
I use Grails 2.5.0 and plugin grails-cfx
Grails-cfx configuration in Config.groovy
birCompanyDataEndPoint {
wsdl = "wsdl/UslugaBIRzewnPubl.xsd"
namespace = "pl.truesoftware.crm.company.regon"
client = true
contentType = "application/soap+xml"
mtomEnabled = true
exsh = true
or = true
wsdlArgs = ['-autoNameResolution']
// outInterceptors = 'smartApiMetaOutInterceptor'
clientInterface = IUslugaBIRzewnPubl
serviceEndpointAddress = "https://wyszukiwarkaregontest.stat.gov.pl/wsBIR/UslugaBIRzewnPubl.svc"
}
Example
Plain SOAP request from client service
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:DaneKomunikat xmlns="http://CIS/BIR/PUBL/2014/07/DataContract" xmlns:ns2="http://CIS/BIR/PUBL/2014/07" xmlns:ns3="http://CIS/BIR/2014/07" xmlns:ns4="http://schemas.microsoft.com/2003/10/Serialization/"/>
</soap:Body>
</soap:Envelope>
With using annotation #Addressing(enabled=true, required=true)
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Action xmlns="http://www.w3.org/2005/08/addressing">http://CIS/BIR/PUBL/2014/07/IUslugaBIRzewnPubl/DaneKomunikat</Action>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:f43e7c86-99dd-42fc-a626-ccbd44136682</MessageID>
<To xmlns="http://www.w3.org/2005/08/addressing">https://wyszukiwarkaregontest.stat.gov.pl/wsBIR/UslugaBIRzewnPubl.svc</To>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
</soap:Header>
<soap:Body>
<ns2:DaneKomunikat xmlns="http://CIS/BIR/PUBL/2014/07/DataContract" xmlns:ns2="http://CIS/BIR/PUBL/2014/07" xmlns:ns3="http://CIS/BIR/2014/07" xmlns:ns4="http://schemas.microsoft.com/2003/10/Serialization/"/>
</soap:Body>
</soap:Envelope>
Expected
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ns="http://CIS/BIR/PUBL/2014/07">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:To>https://wyszukiwarkaregontest.stat.gov.pl/wsBIR/UslugaBIRzewnPubl.svc</wsa:To>
<wsa:Action>http://CIS/BIR/PUBL/2014/07/IUslugaBIRzewnPubl/DaneKomunikat</wsa:Action>
</soap:Header>
<soap:Body>
<ns:DaneKomunikat/>
</soap:Body>
</soap:Envelope>
Update with solution
Created two cfx interceptor. First convert soap addressing tags(Action, To) to acceptable format
public class BirSoapHeaderInterceptor extends AbstractSoapInterceptor
{
static String birSID = ""
public BirSoapHeaderInterceptor() {
super(Phase.PRE_PROTOCOL);
}
#Override
public void handleMessage(SoapMessage message) throws Fault
{
try
{
message.put("disable.outputstream.optimization", true)
List<Header> soapHeaders = message.getHeaders()
//----------------- copy values from old header
String wsaAction = ""
String wsaTo = ""
soapHeaders.each { tag ->
log.debug("Soap request header tag: ${tag.name} ${tag.dataBinding}")
String tagName = (tag.name as String)
def objectValue = tag.object?.value
if (!wsaAction && tagName.contains("Action"))
wsaAction = objectValue?.value
if (!wsaTo && tagName.contains("To"))
wsaTo = objectValue?.value
}
soapHeaders.clear()
//-----------------wsa:To
Header headTo = new Header(new QName("http://www.w3.org/2005/08/addressing", "To", "wsa"), wsaTo, new JAXBDataBinding(String.class))
soapHeaders.add(headTo)
//-----------------wsa:Action
Header headAction = new Header(new QName("http://www.w3.org/2005/08/addressing", "Action", "wsa"), wsaAction, new JAXBDataBinding(String.class))
soapHeaders.add(headAction)
message.put(Header.HEADER_LIST, soapHeaders)
//Session identyficator in HTTP Header
if(birSID.length())
{
Map<String, List<String>> outHeaders = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS)
outHeaders.put("sid", Arrays.asList(birSID));
message.put(Message.PROTOCOL_HEADERS, outHeaders);
}
} catch (SOAPException e)
{
log.error(e)
}
}
}
Second interceptor converts attributes 'xmlns:soap', 'xmlns:wsa', 'xmlns:soap' with acceptable namespaces
class BirSoapContextInterceptor implements SOAPHandler<SOAPMessageContext>
{
/*
Based on https://stackoverflow.com/questions/10678723/changing-jax-ws-default-xml-namespace-prefix
*/
public boolean handleMessage(final SOAPMessageContext context)
{
try
{
SOAPMessage soapMsg = context.getMessage();
SOAPEnvelope envelope = soapMsg.getSOAPPart().getEnvelope()
soapMsg.getSOAPPart().getEnvelope().removeAttributeNS("http://schemas.xmlsoap.org/soap/envelope/", "soap");
soapMsg.getSOAPPart().getEnvelope().removeAttributeNS("http://www.w3.org/2000/xmlns/", "soap");
soapMsg.getSOAPPart().getEnvelope().removeAttribute("xmlns:soap");
soapMsg.getSOAPPart().getEnvelope().removeNamespaceDeclaration("xmlns:soap")
envelope.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:soap", "http://www.w3.org/2003/05/soap-envelope");
envelope.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns", "http://CIS/BIR/PUBL/2014/07");
soapMsg.getSOAPHeader().setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:wsa", "http://www.w3.org/2005/08/addressing")
soapMsg.getSOAPHeader().setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:soap", "http://www.w3.org/2003/05/soap-envelope");
soapMsg.saveChanges()
context.setMessage(soapMsg)
} catch (SOAPException e)
{
e.printStackTrace();
}
return true;
}
#Override
boolean handleFault(SOAPMessageContext context) {
return false
}
#Override
void close(MessageContext context) {
log.debug("Closing...")
}
#Override
Set<QName> getHeaders() {
return null
}
}

Spring WS - unable to return a JAXB response

As described in this tutorial: http://docs.spring.io/spring-ws/site/reference/html/tutorial.html
I have a Spring WS method which receives a request:
#PayloadRoot(localPart = "HolidayRequest", namespace = NAMESPACE_URI)
#Namespace(prefix = "hr", uri= NAMESPACE_URI )
#ResponsePayload
public void handleHolidayRequest(#XPathParam("//hr:HolidayRequest") Object request) throws Exception {
}
and I can read the values passed in. Now if I try to send a response:
#PayloadRoot(localPart = "HolidayRequest", namespace = NAMESPACE_URI)
#Namespace(prefix = "hr", uri= NAMESPACE_URI )
#ResponsePayload
public HolidayResponse handleHolidayRequest(#XPathParam("//hr:HolidayRequest") Object request) throws Exception {
}
HolidayResponse response = new HolidayResponse(); // JAXB object
response.setIsApproved( false );
response.setEmpId( BigInteger.ONE );
return response;
The SOAP client receives a fault response:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">javax.xml.bind.JAXBException
- with linked exception:
[java.lang.NullPointerException]</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Any ideas what I might be doing wrong?
NOTE: I have tried wrapping the response:
return new JAXBElement( new QName("HolidayResponse"), HolidayResponse.class, response );

Categories

Resources