On my current project, my team has to consume numerous web services from an external, SOAP provider. This may seem trivial, but the
Grails Framework provides numerous ways to expose web services, but could offer few solutions to consume the web services. I initially experimented with
GroovyWS. After some success, I had to ditch it because the services that we are working with are too complex for that library.
The solution I decided to use back to Java. Since Groovy runs on the JVM, a Groovy developer is armed with the same libraries as a Java devloper. This makes the Groovy language very powerful (if it needs to be). To consume a SOAP service, import the required Java libraries - I used the Apache Commons Libraries.
import org.apache.commons.httpclient.*;
The implementation of the calls may seem primitive, but what it lacks in beauty it makes up for in speed - I was shocked at the quickness of the service calls. To call the service, we are going to pass a small snippet of XML to the web service and parse the results. First, define the url of the web service and the XML request (which I of course called payload):
def url = "http://www.webservicex.net/CurrencyConvertor.asmx?wsdl"
def payload = """
<?xml version="1.0" encoding="UTF-8" standalone="no"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.webserviceX.NET/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ><SOAP-ENV:Body><tns:ConversionRate xmlns:tns="http://www.webserviceX.NET/"><tns:FromCurrency>USD</tns:FromCurrency><tns:ToCurrency>EUR</tns:ToCurrency></tns:ConversionRate></SOAP-ENV:Body></SOAP-ENV:Envelope>
"""
Please don't be afraid of the payload. I was at first, but the ever so awesome
SOAP Client is used to make SOAP requests and responses a breeze. The payload string is generated by the SOAP Client then pasted in the source code. The payload string will differ depending on what function is being used - notice in the example string that I am converting USD to EUR.
From here, we need to send the request to the server and recieve its response - hopefully a
200 response.
def method = new PostMethod(url)
def client = new HttpClient()
payload = payload.trim()
method.addRequestHeader("Content-Type","text/xml")
method.addRequestHeader("Accept","text/xml,application/xml;q=0.9")
method.setRequestEntity(new StringRequestEntity(payload))
def statusCode = client.executeMethod(method)
println "STATUS CODE : ${statusCode}"
def resultsString = method.getResponseBodyAsString()
method.releaseConnection()
return resultsString
This makes the request to the server and returns a string.
From here, we can parse the string and reap the benefits of not having to write the complex functionality that the web service provided our application.
This method of consuming a web service also appears in Scott Davis'
Book,
Groovy Recipes: Greasing the Wheels of Java. All I want to know is why could I not find this information 2 months ago? This book is a must for any Groovy/Grails geek.
I know this is a trivial example, but trust in this method and the the methods described in the previous post. Please post a comment if a more complex example is needed - I had a hard time finding resources when I was searching and want to help out anyone that I can.
Big thanks to the
formatmysourcecodeblog for the cool source code boxes - I will definitely be using them again.