0bj3ct
0bj3ct

Reputation: 1490

Consume SOAP web service without wsdl using spring framework

I have to call a web service located in http://ip:port/ws which has no wsdl.

I can send an HTTP POST using Spring framework's RestTemplate and get answer as raw input from the service. But this is annoying a bit, that's why I am looking for the correct way to consume this web service without WSDL.

Can anybody suggest a 'best practice' way for this task?

Upvotes: 3

Views: 10867

Answers (3)

0bj3ct
0bj3ct

Reputation: 1490

I could not find the best solution, and did some workaround. So as we know the SOAP call in HTTP environment is a standard HTTP POST with the soap envelope in HTTP POST body. So I did the same. I stored the xml soap requests in different place just not mess with the code:

public static final String REQ_GET_INFO = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:xyz\">" +
                                                            "   <soapenv:Header/>" +
                                                            "   <soapenv:Body>" +
                                                            "      <urn:export>" +
                                                            "         <cardholderID>%s</cardholderID>" +
                                                            "         <bankId>dummy_bank</bankId>" +
                                                            "      </urn:export>" +
                                                            "   </soapenv:Body>" +
                                                            "</soapenv:Envelope>";

And in service layer I used RestTemplate post call with required headers:

@Value("${service.url}") // The address of SOAP Endpoint
private String wsUrl;

public OperationResponse getCustomerInfo(Card card) {
    OperationResponse operationResponse = new OperationResponse(ResultCode.ERROR);

    try {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "text/xml");

        HttpEntity<String> request = new HttpEntity<>(String.format(Constants.SoapRequest.REQ_GET_INFO, 
                                                                            card.getCardholderId()), headers);

        String result = restTemplate.postForObject(wsUrl, request, String.class);


        if(!result.contains("<SOAP-ENV:Fault>")) {
            // Do SOAP Envelope body parsing here
        }
    }
    catch(Exception e) {
        log.error(e.getMessage(), e);
    }

    return operationResponse;
}

A little bit of dirty job, but it worked for me :)

Upvotes: 2

David
David

Reputation: 2702

If you're really lucky, it'll return some consistent XML that you might be able to throw an XPath parser at to extract the bits you need. You might be able to tease out the XML schema either from the data it returns (look for a namespace declaration at the top of the document somewhere, and see if you can follow the URI it references), or drop the data into an on-line schema generator like this one

Upvotes: 1

ThomasRS
ThomasRS

Reputation: 8287

There is really no best practice, recreating the WSDL or at least the XML Schema seems like your only option to improve upon your current approach.

Upvotes: 1

Related Questions