Search code examples
javaspringspring-bootsoap-client

SOAP web service call using WebServiceTemplate in SpringBoot client


I am calling a SOAP web service using WebServiceTemplate. I am able to call the service using SOAP UI with following input and getting the correct response.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:abc="http://abc.hs.com/">
      <soapenv:Header>
                <version>1<version>
   </soapenv:Header>
   <soapenv:Body>
      <abc:getUser>
         <userId>pan</userId>
      </abc:getUser>
   </soapenv:Body>
</soapenv:Envelope>

But when calling using WebserviceTemplate as below:

public String getUser(String userId) {
        List<String> detail = new ArrayList<String>();
        try {
            template = new WebServiceTemplate(marshaller);
            String requestPayload = getXmlInput();// This is same xml I am sending using SOAPUI 
            StreamSource source = new StreamSource(new StringReader(requestPayload));
            StreamResult result = new StreamResult(System.out);
            template.sendSourceAndReceiveToResult("http://localhost:8080/HERSvc/InsService", source,
                    new WebServiceMessageCallback() {
                        public void doWithMessage(WebServiceMessage message) throws IOException {
                        TransportContext context = TransportContextHolder.getTransportContext();
                        HttpUrlConnection connection = (HttpUrlConnection) context.getConnection();
                        connection.addRequestHeader("Content-Type", "text/xml; charset=utf-8");
                        connection.addRequestHeader("soapAction", "");
                }
            },result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

I am getting following error at server side: E org.apache.axis2.engine.AxisEngine receive The endpoint reference (EPR) for the Operation not found is http://localhost:8080/HERSvc/InsService and the WSA Action = . If this EPR was previously reachable, please contact the server administrator.

Client side error message : There was an unexpected error (type=Internal Server Error, status=500).

After going through https://stackoverflow.com/questions/5981379/the-endpoint-reference-epr-for-the-operation-not-found-is I added Content-Type and soapAction in header

NOTE: I suspect problem is with my requestPayload which is not formed properly. It is same string used in SOAP UI. It seems the input is transformed as Body

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<soapenv:Envelope xmlns:abc="http://abc.hs.com/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
    <version>1<version>
</soapenv:Header>
    <soapenv:Body>
        <abc:getUser>
            <userId>pan</userId>
        </abc:getUser>
    </soapenv:Body>
</soapenv:Envelope>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> 

Solution

  • The issue was that required Header was not formed properly. Initially I wasn't able to create objectPayload, so unable to use marshalSendAndReceive. So, to create proper objectPayload I used my wsdl to generate ObjectFactory from command prompt and then imported all the objects created to the project. Use marshalSendAndReceive as follows

    wsimport -d generated http://example.org/stock?wsdl
    
    public User getUser(User user) {
            try {
                template = new WebServiceTemplate(marshaller);
                JAXBElement<?> response =  (JAXBElement<?>)template.marshalSendAndReceive("http://localhost:8080/HERSvc/InsService", 
                new ObjectFactory().createGetUser(user),
                        new WebServiceMessageCallback() {
                            public void doWithMessage(WebServiceMessage message) {
                                try {
                                    SoapMessage soapMessage = (SoapMessage)message;
                                    SoapHeader header = soapMessage.getSoapHeader();
                                    StringSource headerSource = new StringSource("<version>1.0</version>");
                                            Transformer transformer = TransformerFactory.newInstance().newTransformer();
                                            transformer.transform(headerSource, header.getResult());
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                    }) ;
            } catch (IOException e) {
                e.printStackTrace();
            }
            GetUserResponse responseObject = (GetUserResponse)response.getValue();
        User user = responseObject.getReturn();
        }