I'm trying to consume a SOAP web service related from a 3rd party reservations server.
Here's the working request (tested with SOAPUI):
<?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>
<OGHeader transactionID="SomeID" primaryLangID="E"
timeStamp="SomeTimeStamp" channelValidation="false"
timeStampSpecified="true" xmlns="http://webservices.****">
<Origin entityID="****" systemType="****" />
<Destination entityID="***" systemType="**" />
<Authentication>
<UserCredentials>
<UserName>*****</UserName>
<UserPassword>*****</UserPassword>
<Domain>***</Domain>
</UserCredentials>
</Authentication>
</OGHeader>
</soapenv:Header>
<soapenv:Body>
<FutureBookingSummaryRequest
canHandleVaultedCreditCard="true"
xmlns="*****.wsdl">
<AdditionalFilters GetList="true"
IncludePseudoRoom="false" ReservationDisposition="***"
ReservationStatus="RESERVED">
<ns1:HotelReference hotelCode="******"
xmlns:ns1="http://webservices.****" />
</AdditionalFilters>
</FutureBookingSummaryRequest>
</soapenv:Body>
</soapenv:Envelope>
After the generation of needed packages from the WSDL I Created my SOAP client like the following:
public class GloriaWClient {
private static final Logger log = LoggerFactory.getLogger(GloriaWClient.class);
public void getFutureBooking() {
FutureBookingSummaryRequest futurebookingrequest = new FutureBookingSummaryRequest();
/********** Setting the BookingFilters ****************************/
FetchBookingFilters booking_filters = new FetchBookingFilters();
booking_filters.setGetList(true);
booking_filters.setIncludePseudoRoom(false);
booking_filters.setReservationDisposition(ReservationDispositionType.***);
booking_filters.setReservationStatus(ReservationStatusType.***);
/************************** HotelReference ****************************/
HotelReference hotelReference = new HotelReference();
hotelReference.setHotelCode("***");
booking_filters.setHotelReference(hotelReference);
/****************************** REQUEST ********************************/
futurebookingrequest.setCanHandleVaultedCreditCard(true);
futurebookingrequest.setAdditionalFilters(booking_filters);
log.info("Requesting future booking");
try {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(MessageFactory.newInstance());
/******* Adding the SOAP Header ****/
messageFactory.afterPropertiesSet();
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(messageFactory);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.GeneratedPackage's name");
marshaller.afterPropertiesSet();
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.setUnmarshaller(marshaller);
webServiceTemplate.afterPropertiesSet();
FutureBookingSummaryResponse response = (FutureBookingSummaryResponse) webServiceTemplate
.marshalSendAndReceive("https://***********.asmx",
futurebookingrequest, new WebServiceMessageCallback() {
@Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{
try {
// Setting header values
OGHeader ogHeader = new OGHeader();
ogHeader.setTransactionID("****");
ogHeader.setPrimaryLangID("**");
ogHeader.setChannelValidation(false);
log.debug("Created ogHeader");
OGHeaderAuthentication ogHeaderAuth = new OGHeaderAuthentication();
OGHeaderAuthenticationUserCredentials ogHeaderAuthUserCredentials = new OGHeaderAuthenticationUserCredentials();
ogHeaderAuthUserCredentials.setUserName("******");
ogHeaderAuthUserCredentials.setUserPassword("****");
ogHeaderAuthUserCredentials.setDomain("***");
ogHeaderAuth.setUserCredentials(ogHeaderAuthUserCredentials);
ogHeader.setAuthentication(ogHeaderAuth);
// get the header from the SOAP message
SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
log.debug("Got header from the SOAP message");
// create the header element
ObjectFactory factory = new ObjectFactory();
OGHeader futureBookingsummarySoapHeaders = factory.createOGHeader(); futureBookingsummarySoapHeaders.setAuthentication(ogHeaderAuth);
JAXBElement<OGHeader> headers = factory .createOGHeader(futureBookingsummarySoapHeaders);
log.debug("Header element created");
// create a marshaller
JAXBContext context = JAXBContext.newInstance(OGHeader.class);
Marshaller marshaller = context.createMarshaller();
log.debug("Marshaller created");
// marshal the headers into the specified result
marshaller.marshal(headers, soapHeader.getResult());
} catch (Exception e) {
log.error("error during marshalling of the SOAP headers", e);
}
}
});
FutureBookingSummaryResponse msg = (FutureBookingSummaryResponse) response;
} catch (Exception s) {
s.printStackTrace();
}
}
}
Notice That I made sure to set the appropriate Body & header's attributes.
the execution of this Client throws this :
org.springframework.ws.soap.client.SoapFaultClientException: Server did not recognize the value of HTTP Header SOAPAction: . at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38) at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830) at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624) at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) at com.lbc.migration.GloriaClient.GloriaWClient.getFutureBooking(GloriaWClient.java:104) at com.lbc.migration.main.main(main.java:16)
Any IDEA ? or Any related example to create a Spring boot SOAP client with such header ??
You are missing SOAPAction header as shown in your error.
SOAPAction is HTTP Header and its different from SOAPEnvelope Header.
WSDL should have defination of SOAPAction something like,
<soap1:operation style="document" soapAction="petition"
It goes in HTTP Header, not in SOAPEnvelope Header as you have mentioned in your request envelope.
The HTTP Header will look like something like below in TCPMONitor
POST /StockQuote HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "petition"
It should be set something like--
webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
((SoapMessage)message).setSoapAction("http://tempuri.org/Action");
}});