SOAP has a bad reputation in the Ruby community. Most Rubyists prefer Restful services because they are a lot easier to consume and are well supported in tools like Rails. However, there are times where you have to consume a SOAP based web service. In this article, I’ll show you how you can easily consume a SOAP client using JRuby and JAX-WS. The source code for this exercise can be found here.
First, I’m going to grab the wsdl that defines the service we want to consume. Then I’m going to use the JAX-WS wsimport utility to turn the wsdl into java code. Then I’ll compile the Java code and create a jar that I will then use in my ruby code to interact with the web service.
You’ll need to install a couple of things to get started. These include the following:
I’d also suggest RVM but that is optional. If you want to build something based on my example you’ll want to clone my git repository.
> git clone ssh://email@example.com/murphybytes/SampleSoapClient.git
> cd SampleSoapClient
> bundle install
So now you have your environment set up. What next? Let’s think a bit about how we want to structure our project. We are consuming the web service so lets make that a sub project of our main project. We’ll put the web service artifacts in SampleSoapClient/Webservice So we end up with something like this.
I like to include the wsdl files defining the service in my project. With the wsdl files in place I’ll need to write an ant build script that will turn my wsdl into a jar that I can use in my Ruby code. Creating the build.xml is probably the hardest part of the project. Once you create your build script, you can use it as the template for the script to consume any SOAP based web service. Here’s mine.
<project name="OrderHistoryServiceAdapter" basedir="." default="jar">
<taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport">
<classpath path="lib/jaxws-tools.jar" />
<delete includeemptydirs="true" failonerror="false" >
<fileset dir="bin" includes="**/*" />
<fileset dir="generated" includes="**/*" />
<fileset dir="dist" />
<target name="compile" depends="clean">
<javac destdir="bin" >
<src path="test" />
<src path="src" />
<classpath path="lib/junit-4.9b3.jar" />
<target name="jar" depends="compile">
<mkdir dir="dist" />
<jar destfile="dist/OrdersHistoryService.jar" basedir="bin" />
<target name="test" depends="jar" >
<junit printsummary="true" showoutput="true" >
<pathelement path="dist/OrdersHistoryService.jar" />
<pathelement path="lib/junit-4.9b3.jar" />
<formatter type="plain" />
<test name="com.eris.orderhistory.test.SessionTokenManagerTest" />
Now, using JRuby, we can interact with our web service using pure Ruby code. All we have to do is add the requisite requires and import the classes that we want to use. Here’s an example.
# required to import native java
# the jar that implements our web service
# import native java classes
That’s all there is to it!