Send SOAP Request with XML Parameter UTF-8 Java - java

I am looking for an advice here with my problem. I have a SOAP Request in Java with the following code:
private static SOAPMessage createSOAPRequest(String shellType, String filterCondition,
Map<String, String> AndySiteToSync) throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage soapMessage = messageFactory.createMessage();
createSoapEnvelope(soapMessage, shellType, filterCondition, AndySiteToSync);
MimeHeaders headers = soapMessage.getMimeHeaders();
soapMessage.saveChanges();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
soapMessage.writeTo(stream);
return soapMessage;
}
I have the following structure on the XML.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:gen="http://general.service.webservices.skire.com">
<soap:Header/>
<soap:Body>
<gen:updateShell>
<!--Optional:-->
<gen:shortname>xxx</gen:shortname>
<!--Optional:-->
<gen:authcode>xxx</gen:authcode>
<!--Optional:-->
<gen:shellType>xxx</gen:shellType>
<!--Optional:-->
<gen:shellXML>
<![CDATA[
<List_Wrapper>
<_shell>
<paraminside>letterwithutf8_ññ</uuu_longitude>
</_shell>
</List_Wrapper>
]]>
</gen:shellXML>
</gen:updateShell>
</soap:Body>
</soap:Envelope>
It is working very good with characters without ñ or áéíóú, but when I pass a parameter with ñ for example I see on the result ñ. When I print the input xml it is showing the XML fine with the correct characters but when I send the request the result is showing the incorrect character (ñ)
I paste the same input XML in the SOAPUI and the result was good, the ñ characters was introduce fine. The problem is when I send the request using Java.
I assumed it is the encoding of the message. So I added these lines before saveChanges:
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("Content-Type", "application/soap+xml;charset=UTF-8");
Alse test with:
headers.setHeader("Content-Type", "application/soap+xml;charset=UTF-8");
These headers are the same as the SOAPUI, with the exception of the "action"
I made sure the headers were ok printing it.
for (int iii = 0; iii < headers.getHeader("Content-Type").length; iii++) {
System.out.println((headers.getHeader("Content-Type"))[iii]);
}
and I got the response application/soap+xml;charset=UTF-8
This way I am creating the connection:
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(....))
SOAPUI
POST https://xxxxxxxxxxxxxxxxx/WebServices HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="urn:xxxxxxx"
Content-Length: 4381
Host: xxxxxxxxxxxxxxxx
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Thanks.
===========================================
Thanks to Andreas I did some more testing and the encoding problem was before the SOAP Request, I got the information from a URL in json format with the following code:
JSONArray jsonDataFinal = new JSONArray();
JSONArray jsonData = (JSONArray) parser.parse(readUrl(URL));
And then:
List<Map<String,String>> mergeArray = new ArrayList<Map<String,String>>();
Map<String, String> mergeObj = null;
for (Object o : sitesArray)
{
if((siteAndy.get("xxxx")) == null) mergeObj.put("xxxx", "");
else mergeObj.put("xxxx", ((String) siteAndy.get("xxxx")).trim());
}
At what point should I use the utf-8 encoding?
Thanks

I change to this:
reader = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));
And my problem was fix.
Thanks!!

Related

How to set up SOAPMessage boundary?

I am sending a SoapMessage in java. I keep having problem with setting up proper headers, precisely the part of Content-Type which should looks like this:
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart#soapui.org>"; start-info="text/xml"; boundary="the boundary of my soapmessage"
I don't know how to add the boundary parameter to my headers so it matches the rest of soap message.
My soap message looks like this:
------=_Part_0_5841104.1608651610791
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart#soapui.org>
MYXML
------=_Part_0_5841104.1608651610791
Content-Type: application/zip; name=Worker.zip
Content-Transfer-Encoding: binary
Content-ID: <MYFILE.zip>
Content-Disposition: attachment; name="MYFILE.zip"; filename="MYFILEr.zip"
MYATTACHMENT
The boundary part in soapbody is generated automatically (------=_Part_0_5841104.1608651610791) and it changes every time I send the message. When I am trying to add headers I do it this way:
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String authString = "login" + ":" + "password";
String enc = java.util.Base64.getEncoder().encodeToString((authString).getBytes(StandardCharsets.UTF_8));
MimeHeaders hd = soapMessage.getMimeHeaders();
hd.addHeader("POST","where");
hd.addHeader("Accept-Encoding","gzip,deflate");
hd.addHeader("Content-Type","multipart/related; type=\"application/xop+xml\"; start=\"<rootpart#soapui.org>\"; start-info=\"text/xml\"; boundary=\"----=_????????\"");
hd.addHeader("SOAPAction","Action");
hd.addHeader("MIME-Version","1.0");
hd.addHeader("Host","MyHost");
hd.addHeader("Connection","Keep-Alive");
hd.addHeader("User-Agent","Apache-HttpClient/4.1.1 (java 1.5)");
hd.addHeader("Authorization", "Basic " + enc);
How can I add this proper boundary to my headers?
I have struggled with this today and this was the first hit I found.
When you are done creating your SOAPMessage call saveCanges() on it. This will populate the mimeheaders with correct content-type with the bountary in it.
SOAPMessage msg = //create message...
msg.saveChanges();
msg.getMimeHeaders(); //Now contains a content-type with boundary that you can send as request properties.
Hope this helps anyone having this problem.

Unable to set Content-Type on SOAP Request

I'm sending a SOAP call to a server, and the server insists on a certain Content-Type. I'm trying to set the content type but it doesn't seem to be transmitted properly.
I get a response from the server:
415 Cannot process the message because the content type 'text/xml;
charset=utf-8' was not the expected type 'application/soap+xml;
charset=utf-8'
My rough code:
val soapConnectionFactory = SOAPConnectionFactory.newInstance()
val soapConnection = soapConnectionFactory.createConnection()
val url = "https://secure.com"
val messageFactory = MessageFactory.newInstance()
val soapMessage = messageFactory.createMessage()
// (create envelope)
val headers = soapMessage.mimeHeaders
headers.setHeader("Content-Type", "application/soap+xml; charset=utf-8")
soapMessage.saveChanges()
val soapResponse = soapConnection.call(soapMessage, url)
soapConnection.close()
Debugging through, the content type appears to be set properly up to the soapConnection.call(). Any ideas?
You are creating a default MessageFactory:
val messageFactory = MessageFactory.newInstance()
As doc states this method
Creates a new MessageFactory object that is an instance of the default implementation (SOAP 1.1)
SOAP 1.2 message content type is "application/soap+xml", whereas SOAP 1.1 is "text/xml" (http://www.w3.org/TR/soap12-part0/#L4697).
Try to create a message factory instance providing the SOAP 1.2 as protocol
val messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL)

Java Programatically Request SOAP Web Service Issue

I'm attempting to make a SOAP request to an end point programmatically through Java. I'm relatively new to Java and web services so I'm not sure what I'm doing wrong here.
Also I print out the SOAP message and can paste that into a tool like postman and enter the end point and a post is successful. So i think something with my request is not correct here.
Here is my code:
System.out.println("hey now!!!!");
try {
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection connection = scf.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage message = mf.createMessage();
SOAPBody body = message.getSOAPBody();
SOAPHeader header = message.getSOAPHeader();
SOAPElement getOpenPOs = body.addChildElement("GetOpenPOs", "", "https://www.autocrib.net");
SOAPElement U = getOpenPOs.addChildElement("U");
U.addTextNode("u");
SOAPElement P = getOpenPOs.addChildElement("P");
P.addTextNode("p");
SOAPElement N = getOpenPOs.addChildElement("N");
N.addTextNode("n");
SOAPElement Processed = getOpenPOs.addChildElement("Processed");
Processed.addTextNode("false");
SOAPElement StationEnd = getOpenPOs.addChildElement("StationEnd");
StationEnd.addTextNode("");
SOAPPart sp = message.getSOAPPart();
SOAPEnvelope envelope = sp.getEnvelope();
//MimeHeaders headers = message.getMimeHeaders();
//header.setHeader("Content-Type", "text/xml");
//message.getMimeHeaders().addHeader("SOAPAction", "GetOpenPOs");
message.getMimeHeaders().addHeader("Content-Type", "text/xml");
header.setAttribute("Content-Type", "text/xml");
message.saveChanges();
System.out.println("Envelope Body");
message.writeTo(System.out);
System.out.println();
SOAPMessage reply = connection.call(message,
"https://www24.autocrib.net/WebServices/AutoCribWS.asmx");
//String reply2 = connection.call(message, "https://www24.autocrib.net/WebServices/AutoCribWS.asmx").toString();
//sp = reply.getSOAPPart();
//envelope = sp.getEnvelope();
//body = envelope.getBody();
//System.out.println(body.toString());
System.out.println("Done!!!!!!!!!!!!!!!!!!!");
} catch (Throwable t) {
System.out.println("Something went wrong!!! " + t.toString());
}
}
I get this error when I run this code:
Oct 24, 2016 1:56:57 PM com.sun.xml.internal.messaging.saaj.soap.MessageImpl identifyContentType
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
Something went wrong!!! 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?
I'm guessing I need to add the Content-Type header. Am I doing this incorrectly? Any guidance would be great.
Thanks,
Tim
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid
Content-Type:text/html.
The SAAJ API throws an exception because it considers that you web service returns as response text/html content instead of soap/xml content.
So, one advise : study the content returned by postman. Are you sure it is soap/xml format ? It you notice that is not soap/xml content, work on the implementation of your WS and if needed adapt the return to be compliant with the SOAP norm.
Wilco I would like to give you credit for the answer but I don't think I can do that for comments. Your tip helped me figure out that it was indeed returning text/html because of the user agent header I had.
THanks again!!

Soap content length

I look at the following is a sample SOAP 1.1 request to SP server, but its does not matter.
POST /_vti_bin/lists.asmx HTTP/1.1
Host: 192.168.0.25
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://schemas.microsoft.com/sharepoint/soap/GetList"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetList xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>string</listName>
</GetList>
</soap:Body>
</soap:Envelope>
The field Content-Length: length need to be replaced with actual values. What its value? Where is I can see it? Or how to calculate it value before request?
UPD1.
I use ksoap lib
headerPropertyObj = new HeaderProperty("Content-Length", "383"); // should be calc before
headerList.add(headerPropertyObj);
transport.setUrl(URL);
request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("listName", "Tasks");
envelope.setOutputSoapObject(request);
transport.call(SOAP_ACTION, envelope, headerList);
I solved this problem. I wrote myself class
public class MyHttpTransportSE extends Transport
where is I reloaded call method like below
public List call(String soapAction, SoapSerializationEnvelope envelope, List headers)
throws IOException, XmlPullParserException {
if (soapAction == null)
soapAction = "\"\"";
byte[] requestData = createRequestData(envelope);
requestDump = debug ? new String(requestData) : null;
responseDump = null;
connection = getServiceConnection();
connection.setRequestProperty("User-Agent", "kSOAP/2.0");
// connection.setRequestProperty("SOAPAction", soapAction);
// connection.setRequestProperty("Content-Type", "text/xml");
connection.setRequestProperty("Content-Type", "application/soap+xml");
connection.setRequestProperty("Connection", "close");
connection.setRequestProperty("Content-Length", "" + requestData.length);
Its helped for me, I hope this helps for smb.
The Content-Length value is the length (in bytes) of the body, which starts with the first < and ends with the last character of the body, here > or maybe a newline.
Creating the envelope the right way should be enough, without setting headers by yourself.
http://www.helloandroid.com/tutorials/using-ksoap2-android-and-parsing-output-data
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
httpTransport.debug = true; //try debugging
If your problem relates to sharepoint authentication, then you should add envelope headers properly so the length keeps being calculated by the library itself. Error in authentication when subscribing to a sharepoint webservice using ksoap2-android
this could help: http://davidsit.wordpress.com/2010/03/03/creating-sharepoint-list-items-with-php/

Content-Type Missing "start=" Tag in Java SOAP Client, Attachment not Found by Server

I am creating a Java client for a SOAP service that takes an attachment. I'm using java.xml.soap classes, which I have uses before, but not with attachments. The server claims that my attachment is not included.
I used SoapUI, which works, and wireshark to compare my SOAP message to a working SOAP message. One big difference is that my header does not include "start=".
The working Content-Type looks like this:
Content-Type: multipart/related; type="text/xml"; start=""; boundary="----=_Part_23_6341950.1286312374228"
The Content-Type I get from my Java code is like this:
Content-Type: multipart/related; type="text/xml"; boundary="----=_Part_23_6341950.1286312374228"
No start= even when the content ID is set on the root element. The working and failing SOAP messages are otherwise nearly identical. How can I get the start tag generated, or what are other reasons the server might not see the attachment?
Thanks
SOAPMessage soapMessage =
MessageFactory.newInstance().createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPBody body = soapEnvelope.getBody();
SOAPHeader header = soapMessage.getSOAPHeader();
soapPart.setContentId("<rootpart#here.com>");
MimeHeaders mimeHeaders = soapMessage.getMimeHeaders();
mimeHeaders.addHeader("SOAPAction", "addDocument");
mimeHeaders.addHeader("Accept-Encoding", "gzip,deflate");
Name bodyName = soapEnvelope.createName("Document", "doc",
"http://ns/Document");
SOAPBodyElement document = body.addBodyElement(bodyName);
Name filenameName = soapEnvelope.createName("Filename", "doc",
"http://ns/Document");
SOAPElement filename = document.addChildElement(filenameName);
filename.setValue("filename.txt");
AttachmentPart attachment = soapMessage.createAttachmentPart();
attachment.setContent("Some text", "application/octet-stream");
attachment.setMimeHeader("Content-Transfer-Encoding", "binary");
soapMessage.addAttachmentPart(attachment);
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = scf.createConnection();
URL url = new URL("http://host/Service");
SOAPMessage reply = soapConnection.call(soapMessage, url);
This works for me:
soapMessage.getMimeHeaders().setHeader("Content-Type",
soapMessage.getMimeHeaders().getHeader("Content-Type")[0]+
"; start=\"<rootpart#here.com>\"");

Categories

Resources