Generic Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we're going to show how we can use different command-line interface (CLI) processes to consume a SOAP web service.

2. SOAP Web Service

To run the examples in this post, we'll use the SOAP web service developed in a previous article. In a nutshell, this service has an endpoint that clients can access, providing a country name in the request. The service replies with the name of the country's capital, population, and currency.

3. cURL

Let's start with cURL because it's probably the most widely used command-line tool for transferring data via network protocols. To test a SOAP web service, we just need to make HTTP requests with a SOAP envelope in the request body.

For our web service, a simple HTTP POST request is:

curl -v --request POST --header "Content-Type: text/xml;charset=UTF-8" \
--data \
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:gs="http://www.baeldung.com/springsoap/gen"> \
<soapenv:Header/> \ 
<soapenv:Body> \ 
<gs:getCountryRequest> <gs:name>Poland</gs:name> </gs:getCountryRequest> \ 
</soapenv:Body> \ 
</soapenv:Envelope>' \
http://localhost:8080/ws

We don't need to specify that we're using HTTP because it's the default protocol in cURL. Since we're testing the request, we use the verbose mode via the -v option.

Inside the SOAP envelope, we specify the country (Poland) and finish the command with the SOAP server URL. We have installed the server locally on our computer, using the example from our earlier article.

Since we're using the -v option, we get a detailed response:

* Connected to localhost (::1) port 8080 (#0)
> POST /ws HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.55.1
> Accept: */*
> Content-Type: text/xml;charset=UTF-8
> Content-Length: 282
>
* upload completely sent off: 282 out of 282 bytes
< HTTP/1.1 200
< Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
< SOAPAction: ""
< Content-Type: text/xml;charset=utf-8
< Content-Length: 407
< Date: Sun, 18 Jul 2021 23:46:38 GMT
<
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><ns2:getCountryResponse xmlns:ns
2="http://www.baeldung.com/springsoap/gen"><ns2:country><ns2:name>Poland</ns2:name><ns2:population>38186860</ns2:population><ns2:capital>Warsaw
</ns2:capital><ns2:currency>PLN</ns2:currency></ns2:country></ns2:getCountryResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>* Connection #0 to hos
t localhost left intact

The request and response messages for SOAP web services can be long, so it's more convenient to store them in files. If we save the request body in request.xml and redirect the output of the response to the file response.xml, the command, in this case, is very simple:

curl --header "Content-Type: text/xml;charset=UTF-8" -d @request.xml -o response.xml http://localhost:8080/ws

In general, it's not necessary to specify POST in the command as we did before because it's inferred by cURL.

If we need to read the response in the terminal, it's best to pipe the command with xmllint to get the XML response properly formatted:

curl --request POST --header "Content-Type: text/xml;charset=UTF-8" -d @request.xml http://localhost:8080/ws | xmllint --format -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   725  100   407  100   318    407    318  0:00:01 --:--:--  0:00:01 15425<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <ns2:getCountryResponse xmlns:ns2="http://www.baeldung.com/springsoap/gen">
      <ns2:country>
        <ns2:name>Poland</ns2:name>
        <ns2:population>38186860</ns2:population>
        <ns2:capital>Warsaw</ns2:capital>
        <ns2:currency>PLN</ns2:currency>
      </ns2:country>
    </ns2:getCountryResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

4. Wget

Let's make the same request using Wget:

wget --post-file=request.xml --header="Content-Type: text/xml" http://localhost:8080/ws -O response.xml

The response is:

Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8080... connected.
HTTP request sent, awaiting response... 200
Length: 407 [text/xml]
Saving to: ‘response.xml’

The syntax is similar to cURL, and we can have the request and response bodies stored in files as before.

5. HTTPie

Wget and cURL are very useful commands to quickly test a SOAP server. They're available with all major OS distributions. They can also be easily integrated with shell scripts.

The advantage of HTTPie is that it provides a very intuitive way to interact with Web Services. As stated in the documentation: “HTTPie is designed for testing, debugging, and generally interacting with APIs & HTTP servers. They use simple and natural syntax and provide formatted and colorized output.”

Let's issue the simple request we did before, this time using HTTPie:

echo '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:gs="http://www.baeldung.com/springsoap/gen"> \
<soapenv:Header/> \ 
<soapenv:Body> \ 
<gs:getCountryRequest> <gs:name>Poland</gs:name> </gs:getCountryRequest> \ 
</soapenv:Body> \ 
</soapenv:Envelope>' | \
http -b POST http://localhost:8080/ws 'Content-Type:text/xml'

If we want to extract the request body from a file:

http -b POST http://localhost:8080/ws 'Content-Type:text/xml' < request.xml

It's as simple as using file input redirection.

For more details on how to use HTTPie, refer to the documentation.

6. Summary

We've seen simple examples of how to quickly call a SOAP Web Service from the command line using cURL, Wget, and HTTPie. We also have done a brief comparison of the three tools and when to use them.

Generic bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
Generic footer banner
Comments are closed on this article!