SOAP request to WebService with java
A SOAP request is an XML file consisting of the parameters you are sending to the server.
The SOAP response is equally an XML file, but now with everything the service wants to give you.
Basically the WSDL is a XML file that explains the structure of those two XML.
To implement simple SOAP clients in Java, you can use the SAAJ framework (it is shipped with JSE 1.6 and above):
SOAP with Attachments API for Java (SAAJ) is mainly used for dealing directly with SOAP Request/Response messages which happens behind the scenes in any Web Service API. It allows the developers to directly send and receive soap messages instead of using JAX-WS.
See below a working example (run it!) of a SOAP web service call using SAAJ. It calls this web service.
import javax.xml.soap.*;
public class SOAPClientSAAJ {
// SAAJ - SOAP Client Testing
public static void main(String args[]) {
/*
The example below requests from the Web Service at:
http://www.webservicex.net/uszip.asmx?op=GetInfoByCity
To call other WS, change the parameters below, which are:
- the SOAP Endpoint URL (that is, where the service is responding from)
- the SOAP Action
Also change the contents of the method createSoapEnvelope() in this class. It constructs
the inner part of the SOAP envelope that is actually sent.
*/
String soapEndpointUrl = "http://www.webservicex.net/uszip.asmx";
String soapAction = "http://www.webserviceX.NET/GetInfoByCity";
callSoapWebService(soapEndpointUrl, soapAction);
}
private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
SOAPPart soapPart = soapMessage.getSOAPPart();
String myNamespace = "myNamespace";
String myNamespaceURI = "http://www.webserviceX.NET";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);
/*
Constructed SOAP Request Message:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="http://www.webserviceX.NET">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<myNamespace:GetInfoByCity>
<myNamespace:USCity>New York</myNamespace:USCity>
</myNamespace:GetInfoByCity>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("GetInfoByCity", myNamespace);
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("USCity", myNamespace);
soapBodyElem1.addTextNode("New York");
}
private static void callSoapWebService(String soapEndpointUrl, String soapAction) {
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl);
// Print the SOAP Response
System.out.println("Response SOAP Message:");
soapResponse.writeTo(System.out);
System.out.println();
soapConnection.close();
} catch (Exception e) {
System.err.println("\nError occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!\n");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
createSoapEnvelope(soapMessage);
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", soapAction);
soapMessage.saveChanges();
/* Print the request message, just for debugging purposes */
System.out.println("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println("\n");
return soapMessage;
}
}
Send Soap request with Java
Below there's a demo of how you could do it. Basically you call addChildElement
and addTextNode
for each element you need.
Make sure you change the endpoint URL and SOAP Action in the main
method before calling.
import javax.xml.soap.*;
public class SOAPClientSAAJ {
// SAAJ - SOAP Client Testing
public static void main(String args[]) {
String soapEndpointUrl = "https://www.w3schools.com/xml/tempconvert.asmx"; // CHANGE ME
String soapAction = "https://www.w3schools.com/xml/CelsiusToFahrenheit"; // CHANGE ME
callSoapWebService(soapEndpointUrl, soapAction);
}
private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
SOAPPart soapPart = soapMessage.getSOAPPart();
String myNamespace = "tem";
String myNamespaceURI = "http://tempuri.org/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("pay", myNamespace);
SOAPElement merchantId = soapBodyElem.addChildElement("merchantId", myNamespace);
merchantId.addTextNode("7507231");
SOAPElement branch = soapBodyElem.addChildElement("branch", myNamespace);
branch.addTextNode("Licensed Branch Name");
SOAPElement alias = soapBodyElem.addChildElement("alias", myNamespace);
alias.addTextNode("Service alias Name");
SOAPElement paymentId = soapBodyElem.addChildElement("paymentId", myNamespace);
paymentId.addTextNode("merchants payment idetificator");
SOAPElement data = soapBodyElem.addChildElement("data", myNamespace);
SOAPElement dataParam = data.addChildElement("param", myNamespace);
SOAPElement dataParamKey = dataParam.addChildElement("key", myNamespace); dataParamKey.addTextNode("account");
SOAPElement dataParamValue = dataParam.addChildElement("value", myNamespace); dataParamValue.addTextNode("account cridentials");
SOAPElement hash = soapBodyElem.addChildElement("hash", myNamespace);
hash.addTextNode("?");
}
private static void callSoapWebService(String soapEndpointUrl, String soapAction) {
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
SOAPMessage soapRequest = createSOAPRequest(soapAction);
SOAPMessage soapResponse = soapConnection.call(soapRequest, soapEndpointUrl);
// Print the SOAP Response
System.out.println("Response SOAP Message:");
soapResponse.writeTo(System.out);
System.out.println();
soapConnection.close();
} catch (Exception e) {
System.err.println("\nError occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!\n");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
createSoapEnvelope(soapMessage);
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", soapAction);
soapMessage.saveChanges();
/* Print the request message, just for debugging purposes */
System.out.println("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println("\n");
return soapMessage;
}
}
How to do a SOAP Web Service call from Java class?
I understand your problem boils down to how to call a SOAP (JAX-WS) web service from Java and get its returning object. In that case, you have two possible approaches:
- Generate the Java classes through
wsimport
and use them; or - Create a SOAP client that:
- Serializes the service's parameters to XML;
- Calls the web method through HTTP manipulation; and
- Parse the returning XML response back into an object.
About the first approach (using wsimport
):
I see you already have the services' (entities or other) business classes, and it's a fact that the wsimport
generates a whole new set of classes (that are somehow duplicates of the classes you already have).
I'm afraid, though, in this scenario, you can only either:
- Adapt (edit) the
wsimport
generated code to make it use your business classes (this is difficult and somehow not worth it - bear in mind everytime the WSDL changes, you'll have to regenerate and readapt the code); or - Give up and use the
wsimport
generated classes. (In this solution, you business code could "use" the generated classes as a service from another architectural layer.)
About the second approach (create your custom SOAP client):
In order to implement the second approach, you'll have to:
- Make the call:
- Use the SAAJ (SOAP with Attachments API for Java) framework (see below, it's shipped with Java SE 1.6 or above) to make the calls; or
- You can also do it through
java.net.HttpUrlconnection
(and somejava.io
handling).
- Turn the objects into and back from XML:
- Use an OXM (Object to XML Mapping) framework such as JAXB to serialize/deserialize the XML from/into objects
- Or, if you must, manually create/parse the XML (this can be the best solution if the received object is only a little bit differente from the sent one).
Creating a SOAP client using classic java.net.HttpUrlConnection
is not that hard (but not that simple either), and you can find in this link a very good starting code.
I recommend you use the SAAJ framework:
SOAP with Attachments API for Java (SAAJ) is mainly used for dealing directly with SOAP Request/Response messages which happens behind the scenes in any Web Service API. It allows the developers to directly send and receive soap messages instead of using JAX-WS.
See below a working example (run it!) of a SOAP web service call using SAAJ. It calls this web service.
import javax.xml.soap.*;
public class SOAPClientSAAJ {
// SAAJ - SOAP Client Testing
public static void main(String args[]) {
/*
The example below requests from the Web Service at:
https://www.w3schools.com/xml/tempconvert.asmx?op=CelsiusToFahrenheit
To call other WS, change the parameters below, which are:
- the SOAP Endpoint URL (that is, where the service is responding from)
- the SOAP Action
Also change the contents of the method createSoapEnvelope() in this class. It constructs
the inner part of the SOAP envelope that is actually sent.
*/
String soapEndpointUrl = "https://www.w3schools.com/xml/tempconvert.asmx";
String soapAction = "https://www.w3schools.com/xml/CelsiusToFahrenheit";
callSoapWebService(soapEndpointUrl, soapAction);
}
private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
SOAPPart soapPart = soapMessage.getSOAPPart();
String myNamespace = "myNamespace";
String myNamespaceURI = "https://www.w3schools.com/xml/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);
/*
Constructed SOAP Request Message:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="https://www.w3schools.com/xml/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<myNamespace:CelsiusToFahrenheit>
<myNamespace:Celsius>100</myNamespace:Celsius>
</myNamespace:CelsiusToFahrenheit>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("CelsiusToFahrenheit", myNamespace);
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Celsius", myNamespace);
soapBodyElem1.addTextNode("100");
}
private static void callSoapWebService(String soapEndpointUrl, String soapAction) {
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl);
// Print the SOAP Response
System.out.println("Response SOAP Message:");
soapResponse.writeTo(System.out);
System.out.println();
soapConnection.close();
} catch (Exception e) {
System.err.println("\nError occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!\n");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
createSoapEnvelope(soapMessage);
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", soapAction);
soapMessage.saveChanges();
/* Print the request message, just for debugging purposes */
System.out.println("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println("\n");
return soapMessage;
}
}
About using JAXB for serializing/deserializing, it is very easy to find information about it. You can start here: http://www.mkyong.com/java/jaxb-hello-world-example/.
Sending SOAP request to a specific service
The code has to be slightly modified to hit the service.
String url = "http://ec.europa.eu/taxation_customs/vies/services/checkVatService";
is the endpoint you have to hit (this is from the wsdl)
<wsdlsoap:address location="http://ec.europa.eu/taxation_customs/vies/services/checkVatService"/>
Note that when i hit this , i get a soap fault.Looks like the SOAPBody constructed will have to be checked again.
Request SOAP Message = <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:example="http://ec.europa.eu/"><SOAP-ENV:Header/><SOAP-ENV:Body><checkVat><countryCode>...</countryCode><vatNumber>...</vatNumber></checkVat></SOAP-ENV:Body></SOAP-ENV:Envelope>
Response SOAP Message = <?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Unexpected wrapper element checkVat found. Expected {urn:ec.europa.eu:taxud:vies:services:checkVat:types}checkVat.</faultstring></soap:Fault></soap:Body></soap:Envelope>
Edit a full program that works (looks like) , gives me invalid input because i am passing dots (...).
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
public class Main {
public static void main(String args[]) {
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
String url = "http://ec.europa.eu/taxation_customs/vies/services/checkVatService";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// Process the SOAP Response
printSOAPResponse(soapResponse);
soapConnection.close();
} catch (Exception e) {
System.err.println("Error occurred while sending SOAP Request to Server");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://ec.europa.eu/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("tns1", "urn:ec.europa.eu:taxud:vies:services:checkVat:types");
envelope.addNamespaceDeclaration("impl", "urn:ec.europa.eu:taxud:vies:services:checkVat");
// SOAP Body
SOAPBody soapBody = envelope.getBody();
QName bodyQName = new QName("urn:ec.europa.eu:taxud:vies:services:checkVat:types",
"checkVat", "tns1");
SOAPElement soapBodyElem = soapBody.addChildElement(bodyQName);
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement(new QName("urn:ec.europa.eu:taxud:vies:services:checkVat:types",
"countryCode", "tns1"));
soapBodyElem1.addTextNode("...");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement(new QName("urn:ec.europa.eu:taxud:vies:services:checkVat:types",
"vatNumber", "tns1"));
soapBodyElem2.addTextNode("...");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "checkVat");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = soapResponse.getSOAPPart().getContent();
System.out.print("\nResponse SOAP Message = ");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
}
}
Gives back
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>INVALID_INPUT</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
How to prepare SOAP Request and call web service in java
You should have the WSDL
file before you make the request. Then just generate your specific classes using e.g. wsimport tool and then just call the JAX-WS webservice. You do not have to build the request by yourself in this way.
Have a look over this tutorial.
SOAP Webservice Client in Java
I will suggest debugging in 2 steps
1)Use soapUI and check whether your response in coming or not
2)Use the working example i used from mykong
Related Topics
Invalid Signature File Digest for Manifest Main Attributes Exception While Trying to Run Jar File
How to Prevent Parameter Binding from Interpreting Commas in Spring 3.0.5
Execute Jar File with Multiple Classpath Libraries from Command Prompt
Modifying Existing File Content in Java
Extracting Pairs of Words Using String.Split()
Java.Net.Connectexception :Connection Timed Out: Connect
Merging Two JSON Documents Using Jackson
Comparing Date Strings in Java
Why Are Exceptions Not Checked in .Net
What Is the Actual Memory Place for Static Variables
How to Encode Url to Avoid Special Characters in Java
Filling Combobox from Database by Using Hibernate in Java
What Is the Most Accurate Encoding Detector
Maximum Size of Hashset, Vector, Linkedlist
Why Does Collections.Sort Use Mergesort But Arrays.Sort Does Not