Working With Soap Calls
Hey,
SOAP is one of the popular ways of working with web-services another being REST (another of my blog)), while working with any of the SOAP based API, you will get a WSDL (web services description/definition language) describing what all methods are supported by the web service. Its a rather complicated XML document.
A few days back I was working on consuming SOAP based web services. I could not use Groovy WS as the soap calls I needed to make were little complicated, So I used the old httpclient libraries to make the calls. Here is a very simple snippet of the code I was using.
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*
class SoapcallController {
def index = {
def url = "https://www.paymentsample.biz/Gateway.asmx"
def payload ='
ACHACH
'
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()
//println new XmlSlurper().parseText(resultsString).toString()
println resultsString
}
}
In this code we are hitting the “url” with “payload” and getting the response back in the resultsString which itself will be an XML. The payload will change depending upon the WSDL provided.
To generate the payload XML using your own WSDL you can use http://www.soapclient.com/soaptest.html. Its a rather nice tool to use and play before using the web service in your application.
And of course rather than working with XML it is always better to work with objects and method calls,search for wsdl2java or better still Axis2 on google for generating classes from wsdl. I will put a blog on generating classes from WSDL using axis2 api in intelliJ IDEA shortly. 🙂
Thank you for your blog post.Much thanks again. Cool.
I tried using external webservice thru groovyx.net.ws.WSClient but it fails to connect.
I am trying to create the xml for my WSDL Soapclient.
But it gives some error.
wsdl is-
Will appreciate your input.
thx
This was extremely helpful. I have been trying the easy way such as WSclient plugin etc. but none works. The problem is when you’re passing complex objects, it can be difficult to match the WSDL and your passed objects becomes null.
I finally gave up and went to use this method, seems like a brute force solution, BUT IT WORKS.
Another this, it gives a better understanding of SOAP.
Hey guys! GroovyWS can support complex scenarios!
It’s a bit tricky and works well. And code became much more readable than “raw SOAP”. =)
Check it out: http://stackoverflow.com/questions/3317453/groovyws-and-complex-requests/3645389#3645389
@ lukas
Thanks for the pointing it out. I have updated the blog. Hope it will be more useful now.
I see that this is a SSL SOAP service; however, when I try to execute your code against a SSL service, I get the following exceptions:
Exception thrown: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
at org.apache.commons.httpclient.methods.StringRequestEntity.writeRequest(StringRequestEntity.java:146)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at prueba.run(prueba.groovy:35)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014)
… 18 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
… 22 more
And the owner of the WS keeps telling me that there is no certificate. Any clue?
Thanks.
Sachin: If this is for somebody new to SOAP then it’s even worse of an example of SOAP because the first thing a newbie would ask is “how did you know what namespaces to put in the XML?”. I think the title of your post is misleading in this respect. It has nothing to do with SOAP – it’s a pure http get operation.
@ Lukas
Very true, I completely agree with you. I mentioned about Axis2 and wsdl2java in post. The whole purpose of this blog was to give an idea to a new person who has never implemented a soap call about how things are working behind the scene. This code is never meant to be a part of a production system, at best it can be used at making an isolated call to a server in a POC.
Yes, that’s how we did things back in the 90’s. The code posted can only be really called a hack and ust a caveat to whoever reads this post: code like the above construction of SOAP requests should never ever make it out into a production or even a testing environment. You’ll get into a world of pain debugging namespace and other issues the moment your XSD becomes just slightly more complex. There are many good webservice libraries out there Axis, Apache CXF etc which will abstract all of this away easily.
I have not worked with PHP at all, so I don’t know what kind of support it provides, but in java you do need to select one of the various ways provided which fit your bill.
Axis2 is a very sophisticated api for achieving most of what you want to do with soap whether its consuming external web services or exposing your own service. Once you are sure of what you want to do, you will find a tool to achieve it in world of java. 🙂
lol looks like good old PHP days in 2006 for me ; ) but pragmatism is good some times.
Just reading a book about web services for pure java and im really disappointed how poor and akward is the soap support in Java …. million ways to do it and not single one is really nice …. its just pain.
Art