I am using the below code to send SOAP request to an endpoint. Since we are experiencing some delay in getting the response from server,i would like to set connection timeout in the code.
Code:
SOAPConnectionFactory soapConnectionFactory =SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
MimeHeaders header = new MimeHeaders();
header.addHeader("Content-type", "application/soap+xml;charset=UTF-8");
header.addHeader("SOAPAction", soapAction);
InputStream is = new ByteArrayInputStream(reqXML.getBytes());
SOAPMessage request = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL).createMessage(header, is);
SOAPMessage soapResponse = soapConnection.call(request, endPoint);
Can some one help me to modify my code to add the timeout value?
I have gone through thread Setting socket read timeout with javax.xml.soap.SOAPConnection ralted to same issue.I am unable to use the solution provided here as I get failure if I do not specify the soap version while creating soap message.
Since, SOAP uses jave.net.URLConnection underneath, you can set the system parameters for connection timeout with
is going to be valid for SOAP as well. You can set the following parameters
-Dsun.net.client.defaultConnectTimeout= < timeout>
-Dsun.rmi.transport.proxy.connectTimeout= < timeout>
Related
I have an application that sends SOAP messages using the SOAP API.
It worked from office perfectly, but when on remote from home using VPN, SOAP calls don't work anymore.
Error message is :
[Fatal Error] :1:1: Content is not allowed in prolog.
Content is not allowed in prolog.
The code I use for soap calls :
SOAPConnection con;
SOAPConnectionFactory conFactory = SOAPConnectionFactory.newInstance();
con = conFactory.createConnection();
URL endpoint = new URL(this.getURI());
SOAPMessage retval = con.call(message, endpoint);
How to add a proxy to make those calls work when using a VPN?
I have to change Mime header for SOAP request, especially the 'content type' header, my code is already working for most of headers, but for some reason I get back the old value for the content type header:
Here is the simplified code with comments:
public static synchronized SOAPMessage sendSoapRequest(String endpointUrl, SOAPMessage request) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
SOAPMessage response = null;
HashMap<String,String> headers = ConfigManager.GetInstance().GetHeaders();
int number_of_retries = ConfigManager.GetInstance().GetNumberOfAttempts();
if (number_of_retries==0)
{
number_of_retries = 10;
}
for (int i = 0; i <=number_of_retries ; i++) {
try {
// Send HTTP SOAP request and get response
SOAPConnection soapConnection
= SOAPConnectionFactory.newInstance().createConnection();
***// here I have mime headers with "Content-Type: text/xml; charset=utf-8"***
if (headers != null)
{
Iterator it = headers.entrySet().iterator();
while (it.hasNext()) {
HashMap.Entry pair = (HashMap.Entry)it.next();
// request.getMimeHeaders().addHeader(pair.getKey().toString(), pair.getValue().toString());
request.getMimeHeaders().setHeader(pair.getKey().toString(), pair.getValue().toString()); ***// I set here: "Content-Type => application/soap+xml"***
}
request.saveChanges(); ***// I got back mime headers with "Content-Type: text/xml;*** charset=utf-8"
}
response = soapConnection.call(request, endpointUrl); ***// If I don't use request.saveChanges(), I also get back mime headers with "Content-Type: text/xml; charset=utf-8"***
// Close connection
soapConnection.close();
return response;
}
}
return null;
}
I don't understand why Content-Type is set back to 'text/xml; charset=utf-8' and how to fix it.
From the code you have and the comment, it seems to me that you are using SAAJ to make a SOAP call to a SOAP 1.2 endpoint and your attempt to set the correct content type is conflicting with whatever SAAJ is doing behind the scenes.
SAAJ allows you to work with an object tree while handling the SOAP details for you. By default it knows to work with SOAP 1.1. The main thing to note here is that for SOAP 1.1. the content type is text/xml and the SOAP XML namespace is http://schemas.xmlsoap.org/soap/envelope/.
You want to send application/soap+xml which is the content type for SOAP 1.2. The SOAP XML namespace will in this case be http://www.w3.org/2003/05/soap-envelope.
So even if you manage to set the desired content type, your XML message created by SAAJ will still be wrong because it will have the namespace of SOAP 1.1. because that's the default.
If you want to call a SOAP 1.2. endpoint you need to tell SAAJ that. Your SAAJ object tree is probably built by using a MessageFactory which has a default instantiation of SOAP 1.1. with:
MessageFactory mf = MessageFactory.newInstance();
If you need SOAP 1.2. you need to tell SAAJ that with this instead:
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
If you do that you will still have the issue with the content type, but this time it will be SAAJ setting application/soap+xml (which is what you want) and also set the proper XML SOAP namespaces within the message.
I'm currently working on a custom SOAP call to a specific domain beyond my control. I know the SOAP call fails but I cannot seem to grab the returned (wrong)value.
Right now I'm using the code below:
Document document = convertStringToDocument(this.MeldingString);
// System.out.println(document);
SOAPConnectionFactory myFct = SOAPConnectionFactory.newInstance();
MessageFactory myMsgFct = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage message = myMsgFct.createMessage();
SOAPConnection myCon = myFct.createConnection();
// Adding parts
SOAPPart mySPart = message.getSOAPPart();
SOAPEnvelope myEnvp = mySPart.getEnvelope();
// Escape the password for usage in header
String escpwd = StringEscapeUtils.escapeJava(this.Password);
// Header
MimeHeaders headers = message.getMimeHeaders();
headers.setHeader("Content-Type", "application/soap+xml;charset=UTF-8");
headers.setHeader("Authorization", this.Username + ":" + escpwd);
// Body
SOAPBody body = myEnvp.getBody();
body.addDocument(document);
// Sending
Core.getLogger("GetResultSOAPmsg").trace("Started");
URL endPt = new URL(
"URL-TO-MY-SERVICE");
System.setProperty("java.net.useSystemProxies", "true");
try {
SOAPMessage reply = myCon.call(message, endPt); "UTF-8");
}
catch(Exception e)
{
e.printStackTrace();
}
This yields the following error which is very common al throughout SO:
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
Now I have read most of these topics already and they explain how this problem is usually solved (namespaces, escaping URL, etc.) but I cannot seem to figure out what is wrong in my case. This is a private service and the other side is unfortunately unable to assist me in this case. The error could be anything from wrong certificates to misspelling the URL.
Therefore I would like to actually SEE onscreen what the actual reply is that was received when making the call. This is going to help me (assuming it's something like a 503, 404 or other page). Regardless of what I do and where I set my breakpoints, there is no information on Reply. It makes somewhat sense since it was unable to create said object but the entire message seems to be discarded.
In what way will I be able to see what the actual reply was to my call before it is discarded?
I think there's a problem with your header
headers.setHeader("Content-Type", "application/soap+xml;charset=UTF-8");
try something like
headers.setHeader("Content-Type", "application/xml;charset=UTF-8");
or
headers.setHeader("Content-Type", "application/json;charset=UTF-8");
depending on the content type that the content type accepted by the service
I am having one function where we generate SOAP request.The request I am able to run in SOAP UI tool and its fetching.
I am creating SOAPMessage like this
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.removeAllHeaders();
headers.addHeader("Content-Type", "text/xml");
SOAPPart soapPart = soapMessage.getSOAPPart();
When I call
SOAPMessage soapResponse = soapConnection.call(soapMessage, url);
get this error:
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
could you help to sort it out?
whether that means connection unable to establish??
Most probably expected HTTP Content-Type header for SOAP messages is application/soap+xml (see XML SOAP).
The exception you get originates from SOAP service container saying that the value of Content-Type header is text/html. I think that SOAP UI set the correct request header value for you.
The header value sent by your code seem to be a default one. You should check what the expected Content-Type value is for you server and ho to set it with your framework/library.
How do I remove a
<soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
node from a response message using Java (or web service configuration)?
I don't want to send back user name and password that is displayed in the header. Do I create a class to extend AbstractSoapInterceptor?
I am using `cxf bus to configure my web service.
I donĀ“t know how are you receiving the SOAP message, but If you can use (or instantiate) a javax.xml.soap.SOAPMessage you remove the header element or attribute that is bothering you:
// Removes the attribute "key" from the message header
message.getSOAPHeader().removeAttribute("key");
Anyway, reusing the same message sounds weird to me, perhaps you should consider creating a new fresh response message:
This statement create a brand new message:
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage message = mf.createMessage(headers, in)
This one, from Mime headers and an inputstream:
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage message = mf.createMessage(headers, in)