I have a Java Soap client that send XML requests with service and method to a remote server but it is anormally slow and can't be used professionnaly.
Is there a way to speed it up or is there a faster way to do Soap requests ?
Thank you for your answers. Here is an extract of my Soap client.
private SOAPMessage makeMessage(String nodeName, String xmlStr, boolean asResponse) throws Exception {
MessageFactory msgFactory = MessageFactory.newInstance();
SOAPMessage message = msgFactory.createMessage();
SOAPPart part = message.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/1999/XMLSchema-instance");
envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/1999/XMLSchema");
SOAPBody body = envelope.getBody();
SOAPElement element = body.addChildElement(envelope.createName("ns1:" + this.method + (asResponse ? "Response" : "")));
element.addAttribute(envelope.createName("xmlns:ns1"), "urn:" + this.service);
element.addAttribute(envelope.createName("ns1"), "http://schemas.xmlsoap.org/soap/encoding");
SOAPElement ele2 = element.addChildElement(envelope.createName(nodeName));
ele2.addAttribute(envelope.createName("xsi:type"), "xsd:string");
ele2.addTextNode(xmlStr);
if (!asResponse) message.saveChanges();
return message;
}
private boolean sendRequest() throws Exception {
try {
SOAPConnectionFactory conFactory = SOAPConnectionFactory.newInstance();
SOAPConnection con = conFactory.createConnection();
URL endpoint = new URL(this.getURI());
SOAPMessage message = this.makeMessage("msgstr", this.request.toString(), false);
SOAPMessage retval = con.call(message, endpoint);
//extraction du XML en String lisible du message SOAP
this.response = extractXML(retval);
} catch (Exception e) {
this.response = e.getMessage();
}
return true;
}
You should enable all the trace/log information of the framework that you are using for the client in order to see where the problem is.
If you are using jax-ws a simple way would be:
System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true");
See:
Tracing XML request/responses with JAX-WS
Related
i need to communicate with two webservices from my application.
For one webservice i need to use soap1_1 version and for the other soap version is soap1_2. In this case what should be the value set for the system property "javax.xml.soap.MessageFactory"
Client 1:
public class SoapClient1 {
protected static Logger _logger = Logger.getLogger ("TEST");
private static Long retryDelay = null;
public String sendSoapMessage (String xml) throws Exception {
SOAPMessage resp = null;
String response = null;
String endpoint = "http:xxxx";
System.setProperty("javax.xml.soap.MessageFactory","com.sun.xml.internal.messaging.saaj.soap.ver1_2.SOAPMessageFactory1_2Impl");
SOAPConnectionFactory connectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = connectionFactory.createConnection();
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
//URL endPoint = new URL(endpoint);
//setting connection time out and read timeout
URL endPoint = new URL (null, endpoint, new URLStreamHandler () {
#Override
protected URLConnection openConnection (URL url) throws IOException {
URL clone = new URL (url.toString ());
URLConnection connection = clone.openConnection ();
connection.setConnectTimeout (60000);
connection.setReadTimeout (60000);
// Custom header
return connection;
}});
try{
start = System.currentTimeMillis();
resp = soapConnection.call(getSoapRequest(xml), endPoint);
end = System.currentTimeMillis();
ByteArrayOutputStream os = new ByteArrayOutputStream();
resp.writeTo(os);
response = os.toString();
if (!resp.getSOAPBody().hasFault()) {
response = "SucCess:" + response;
}else{
response = "FaiLure:" + response;
}
}else{
response = "FaiLure:" + response;
}
}catch(SOAPException se){
_logger.log(Level.ERROR," Service Provisioning Call Failed");
_logger.log(Level.ERROR,"The call duration before SOAPException =" +(end-start)+" ms.");
se.printStackTrace();
throw se;
}
soapConnection.close();
return response;
}
private SOAPMessage getSoapRequest(String xml) throws SOAPException,Exception{
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
/* Create a SOAP message object. */
SOAPMessage soapMessage = mf.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPBody soapBody = soapEnvelope.getBody();
soapEnvelope.getHeader().detachNode();
soapEnvelope.addNamespaceDeclaration("soap","http://yyyy");
SOAPHeader header = soapEnvelope.addHeader();
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
InputStream stream = new ByteArrayInputStream(xml.getBytes());
Document doc = builderFactory.newDocumentBuilder().parse(stream);
_logger.log(Level.DEBUG, "Adding SOAP Request Body");
soapBody.addDocument(doc);
soapMessage.saveChanges();
return soapMessage;
}
}
sample request
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:soap="http://bridgewatersystems.com/xpc/tsc/entity/soap">
<env:Header/>
<env:Body>
<TempTierChangeRequest xmlns="http://bridgewatersystems.com/xpc/tsc/entity/soap" credentials="root" principal="root">
<temp-tier-change xmlns="">
<service-components>
<service-component name="DSL_Tier_2"/>
</service-components>
<duration-sec>300</duration-sec>
<description>1024 SC</description>
<activation-date>2017-02-09T10:29:16</activation-date>
<subscriber-id>26752018010#wholesale1.com</subscriber-id>
<partition-key>26752018010</partition-key>
<ttc-id>3706043</ttc-id>
<validity-period>
<duration>30</duration>
<expires-with-billing-reset>1</expires-with-billing-reset>
</validity-period>
</temp-tier-change>
</TempTierChangeRequest>
</env:Body>
</env:Envelope>
It is not possible to set the value of System variable javax.xml.soap.MessageFactory for two different purposes. The default value is set for SOAP 1.1
Remove the system property javax.xml.soap.MessageFactory and depending on the type of client you are building use
Building the soap message with MessageFactory.newInstance()
If you want SOAP1.1, use the default constructor
MessageFactory factory = MessageFactory.newInstance();
If you want SOAP1.2, use
MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
See Java Tutorial.
JAX-WS clients configured with annotations #BindingType
#BindingType is used when the JAX-WS client is configured using annotations, for example if client is generated from WSDL. The annotation is added to Port to set the binding to SoapBinding.SOAP11HTTP_BINDING or SoapBinding.SOAP12HTTP_BINDING.
#WebService(targetNamespace = "https://myservice.services.com", name = "myserviceProxyProt")
#BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface MyServiceProxyPort {
I have written a Java client code using SAAJ for Primevera P6 webservices. I am getting the below authentication error. I am providing the http username + password to the code but it gives error: SEVERE: SAAJ0008: Bad Response; Unauthorized. Could some one please help me with this issue. I am stuck in this problem since a long time. The wsdl of the web service is: https://sunpower-p6.oracleindustry.com/p6ws-token/services/ProjectService?wsdl.
ERROR:
Request SOAP Message =
11106
Jul 18, 2016 1:03:19 PM com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection post
SEVERE: SAAJ0008: Bad Response; Unauthorized
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad response: (401Unauthorized
My code:
public class TestClient {
/*
Method used to create the SOAP Request
*/
private static SOAPMessage createSOAPRequest() throws Exception {
// Next, create the actual message
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://xmlns.oracle.com/Primavera/P6/WS/Project/V2";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("ProjectService", serverURI);
//start: setting HTTP headers - optional, comment out if not needed
String authorization = Base64Coder.encodeString("xyz:abc");
MimeHeaders hd = soapMessage.getMimeHeaders();
hd.addHeader("Authorization", "Basic " + authorization);
//end: setting HTTP headers
// Create and populate the body
SOAPBody soapBody = envelope.getBody();
// Create the main element and namespace
SOAPElement soapBodyElem = soapBody.addChildElement("ReadProjects", "ProjectService");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Field", "ProjectService");
SOAPElement soapBodyElem2 = soapBodyElem1.addChildElement("Id", "ProjectService");
soapBodyElem2.addTextNode("11106");
hd.addHeader("SOAPAction", serverURI + "ReadProjects");
// Save the message
soapMessage.saveChanges();
// Check the input
System.out.println("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
/**
* Method used to print the SOAP Response
*/
private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
// Create the transformer
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// Extract the content of the reply
Source sourceContent = soapResponse.getSOAPPart().getContent();
// Set the output for the transformation
System.out.println("\nResponse SOAP Message = ");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
System.out.println();
}
public static void main(String[] args) throws Exception {
try {
// First create the connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
//System.out.println(soapConnection);
//Send SOAP Message to SOAP Server
String url = "https://sunpower-p6.oracleindustry.com/p6ws-token/services/ProjectService?wsdl";
// Send the message and get the reply
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// Process the SOAP Response
printSOAPResponse(soapResponse);
soapConnection.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I realize this is an old question but would like to leave some assistance to anyone in the future who ends up here (like I did). There is a few likely situations that I have recently experienced regarding this.
Check that your details are correct, or that the connection is possible. Be 100% sure before moving on.
You will receive an unauthorized error if your database is not correctly configured for some setups (for instance, on JBoss). In my situation the data-source file was not being read properly when it attempted to connect causing the Unauthorized error on the client side.
I'm trying to interact with a SOAP service.
I'm able to get the SOAP response and by using Source sourceContent = soapResponse.getSOAPPart().getContent(); and transformer.transform(sourceContent, result); , I'm able to see what the output/response is and displaying it in the console.
But, I need to extract sessionID from the response and send that sessionID in a different SOAP request.
Please suggest me the extraction method, building a new SOAP request
Parsing is what I need to do!!
Below is the code for sending the request to the SOAP service:
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 = "https://WWW.DUMMYURL.COM";
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 serverURN = "urn:DUMMYURL.COM";
String serverNS0 = "http://WWW.DUMMYURL.COM";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("urn", serverURN);
envelope.addNamespaceDeclaration("ns0", serverNS0);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem1 = soapBody.addChildElement("login","urn");
SOAPElement soapBodyElem2 = soapBodyElem1.addChildElement("username","urn");
#SuppressWarnings("unused")
SOAPElement soapBodyElem3 = soapBodyElem2.addTextNode("USERNAME");
SOAPElement soapBodyElem4 = soapBodyElem1.addChildElement("password","urn");
#SuppressWarnings("unused")
SOAPElement soapBodyElem5 = soapBodyElem4.addTextNode("PASSWORD");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "https://WWW.DUMMYURL.COM" + "login");
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();
String source = sourceContent.toString();
System.out.print("\nResponse SOAP Message = ");
// Format it
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
System.out.println(transformer.toString());
}
Can someone please suggest me a snippet on how should I save the response I'm getting to a file locally?
Currently in the above code the response is getting displayed in the console.
You can use the writeTo method of the SOAPMessage interface to do the same, for example:
FileOutputStream out = new FileOutputStream("somefile");
soapResponse.writeTo(out);
Vinod.
I wrote method, which generate soap message from java string:
private SOAPMessage createRequest(String msg) {
SOAPMessage request = null;
try {
MessageFactory msgFactory = MessageFactory.newInstance();
request = factory.createMessage();
SOAPPart msgPart = request.getSOAPPart();
SOAPEnvelope envelope = msgPart.getEnvelope();
SOAPBody body = envelope.getBody();
StreamSource _msg = new StreamSource(new StringReader(msg));
msgPart.setContent(_msg);
request.saveChanges();
} catch(Exception ex) {
ex.printStackTrace();
}
}
And, after that, I try generate some message. For example:
createRequest("test message");
But here - request.saveChanges(); I catch this exception:
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Error during saving a multipart message
Where is my mistake?
That is because you are not passing a correct protocol formatted message.
Your code doesn't specify which SOAP protocol you want to use, that means it creates a message factory for SOAP 1.1 messages.
Thus, you would need to pass a correct SOAP1.1 message.
I replicated your method like this:
private static SOAPMessage createRequest(String msg) {
SOAPMessage request = null;
try {
MessageFactory msgFactory = MessageFactory
.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
request = msgFactory.createMessage();
SOAPPart msgPart = request.getSOAPPart();
SOAPEnvelope envelope = msgPart.getEnvelope();
SOAPBody body = envelope.getBody();
javax.xml.transform.stream.StreamSource _msg = new javax.xml.transform.stream.StreamSource(
new java.io.StringReader(msg));
msgPart.setContent(_msg);
request.saveChanges();
} catch (Exception ex) {
ex.printStackTrace();
}
return request;
}
and I call it using this string:
String soapMessageString = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body></SOAP-ENV:Body></SOAP-ENV:Envelope>";
createRequest(soapMessageString);
and It works.
I have a working soaprequest in PhP and i'm trying to create a java program that requires the same call, However i am really struggeling to find the way to create the below php code in java, i have found numerus websites explaining soap requests in java but i cant seem to work how how to send the $param_auth array.
Any help would be most appreciated as i've been stuck on this for a while.
Thanks in advance.
$param_auth=array(
'user'=>$username,
'id'=>$userID,
'message'=>$userMessage
);
$soapclient = new soapclient(WebsiteAddress);
$data->_db = $soapclient->call('uploadMessage',$param_auth);
Finally solved my issue (Ive changed Element names etc.), using eclipse shows you the Soap envelope and XML response which i found useful for debugging the envelope).
Hope this helps anyone trying to do similar.
The "UploadMessage" is the "Login" string and the
$param_auth=array(
'user'=>$username,
'id'=>$userID,
'message'=>$userMessage
);
is the Username and Password, (Left out the Message part).
This code sends an Envelope like this the server:-
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:Login="Your URL"><SOAP-ENV:Header/><SOAP-ENV:Body><Login><UserName>YourUserName</UserName><Password>YourPassword</Password></Login></SOAP-ENV:Body></SOAP-ENV:Envelope>
Code To create the above Envelope is below:-
import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class SoapCall {
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 = "Your URL";
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 {
String YourUsername = "UserName";
String YourPassword = "Password";
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "Your URL";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("Login", serverURI);
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("Login");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("UserName");
soapBodyElem2.addTextNode(YourUserName);
SOAPElement soapBodyElem3 = soapBodyElem.addChildElement("Password");
soapBodyElem3.addTextNode(YourPassword);
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "Login");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
/**
* Method used to print the SOAP Response
*/
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);
}
}