How to set character encoding in SOAP request - java

I am calling a SAP SOAP Service from a web servlet in Java. For some reason SAP is giving me an error every time I use special characters in the fields of my request such as 'è' or 'à'. The WSDL of the SOAP Service is defined in UTF-8 and I have set my character encoding accordingly as you can see below. However I am not sure this is the correct way. Also, notice that if I use SOAP UI (with the same envelope) the request works correctly so it must be something on Java side.
URL url = new URL(SOAP_URL);
String authorization = Base64Coder.encodeString(SOAP_USERNAME + ":" + SOAP_PASSWORD);
String envelope = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:urn='urn:sap-com:document:sap:soap:functions:mc-style'><soapenv:Header/><soapenv:Body><urn:ZwsMaintainTkt><item>à</item></urn:ZwsMaintainTkt></soapenv:Body></soapenv:Envelope>";
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(SOAP_TIMEOUT);
con.setRequestMethod("POST");
con.setRequestProperty("Content-type", "text/xml; charset=utf-8");
con.setRequestProperty("SOAPAction", SOAP_ACTION_ZWSMANTAINTKT);
con.setRequestProperty("Authorization", "Basic " + authorization);
con.setDoOutput(true);
con.setDoInput(true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(con.getOutputStream());
outputStreamWriter.write(envelope);
outputStreamWriter.close();
InputStream inputStream = con.getInputStream();

Since a soap-request is xml use the xml-header to specify the encoding of your request:
<?xml version="1.0" encoding="UTF-8"?>
new OutputStreamWriter(con.getOutputStream()) uses the platform-default encoding which most probably is some flavour of ISO8859. Use new OutputStreamWriter(con.getOutputStream(),"UTF-8") instead

Related

How to post request in java to get the response in JSON

I want to post the request in same formate.
POST /mga/sps/oauth/oauth20/token HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic aaabbbCCCdddeeefffGGG
client_id=xxx&client_secret=yyy&grant_type=authorization_code
&code=3v6MJzt9vKtRkxpTFnkJG3IyspWC2k
&redirect_uri=xyz%2Ffolder
I have Implemented but getting bad request and unable to print the post content what I am sending I also want to get the json response after sending this request.
String urlParameters = "grant_type=authorization_code"+"&redirect_uri="+session.getAttribute("redirect_uri")+"&code_verifier="+session.getAttribute("codeVerifier")+"&code="+session.getAttribute("code")+"&state="+session.getAttribute("state");
byte[] postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
int postDataLength = postData.length;
URL url = new URL( "https://example/oauth20/token" );
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("charset", "utf-8");
conn.setRequestProperty("Content-Length",
Integer.toString(postDataLength ));
conn.setRequestProperty("Host","example.com");
conn.setRequestProperty("Authorization","clientID=xyz");
conn.setUseCaches(false);
DataOutputStream wr = new
DataOutputStream(conn.getOutputStream());
wr.write(postData);
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
conn.disconnect();
You have multiple options.
You can start with Java HTTP Client - Refer
The HTTP Client was added in Java 11. It can be used to request HTTP
resources over the network. It supports HTTP/1.1 and HTTP/2, both
synchronous and asynchronous programming models, handles request and
response bodies as reactive-streams, and follows the familiar builder
pattern.
Apache HttpClient - Refer
RestTemplate - Refer
JAX-RS Client - Example
Spring 5 WebClient - Example
OkHttpClient - Example
Comparison

HTTP POST Content Type Not Right

I am trying to pass XML in a URL call and cannot seem to get the parameters right. I am being returned 415 - invalid media type. I know that if I run this URL with the same XML in my REST client (within Firefox) once I put the application/xml header it works fine. However, when I try to do the same in my Java program I get the 415 error.
Where am I going wrong? I think I am defining the content-type properly. I get the error on the line that gets the input stream.
***************** my code ***********************************
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
URL url = new URL(strURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/xml");
connection.setRequestProperty("Content-Type", "application/xml; charset=\"utf-8\"");
connection.setRequestProperty("Authorization", "Basic " + new String(new Base64().encode((strUserName + ":" + strPassword).getBytes())));
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStreamWriter output = new OutputStreamWriter(connection.getOutputStream(), "UTF8");
output.write(strXML);
output.flush();
Document document = builder.parse(connection.getInputStream());
//pull out nodes building a node list
nodeList = document.getElementsByTagName(strElement);
connection.disconnect();
***************** my code ***********************************
***************** my XML **********************************
<?xml version="1.0" encoding="UTF-8"?>\
<rs:model-request throttlesize="5"\
xmlns:rs="http://www.ca.com/spectrum/restful/schema/request"\
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\
xsi:schemaLocation="http://www.ca.com/spectrum/restful/schema/request ../../../xsd/Request.xsd ">\
<rs:target-models>\
<rs:models-search>\
<rs:search-criteria\
xmlns="http://www.ca.com/spectrum/restful/schema/filter">\
<filtered-models>\
<equals>\
<attribute id="0x11ee8">\
<value>15</value> <!-- RTR_Cisco -->\
</attribute>\
</equals>\
</filtered-models>\
</rs:search-criteria>\
</rs:models-search>\
</rs:target-models>\
<rs:requested-attribute id="0x1006e" />\
<rs:requested-attribute id="0x10000" />\
<rs:requested-attribute id="0x10032" />\
<rs:requested-attribute id="0x12de2" />\
</rs:model-request>\
***************** my XML **********************************
I found my problem. It seems that the XML I was plugging into my string variable was missing some key spaces. Specifically I put the XML in a properties file (to simplify making changes down the road). When I did this I, inadvertently, put the continuation characters so that some spaces at end of lines were missing. So, to solve my problem I did 2 things:
1) added needed spaces in several locations
2) removed the "charset=utf-8" from the content-type property so that my setRequestProperty for Content-Type is now only setting to "application/xml"
Thank you to JP Moresmau for being my sounding board. It helped me think through solutions to, eventually, find my problem.

Server returned HTTP response code: 500 when we are sending Arabic language content

We are sending HTTPURLRequest to server.
When we are sending English content its working fine.But, when we are sending Arabic language content we are getting
Server returned HTTP response code: 500
We had written below code
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setRequestProperty("Content-Length", "" + Integer.toString(SendRequest.getBytes().length));
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());
dataout.writeBytes(SendRequest);
dataout.flush();
dataout.close();
BufferedReader bufferreader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
When I use connection.getInputStream() I am getting 500 error
We are using utf-8 also.But, still getting the error
can any one help me
You can use a library to escape the special chars:
StringEscapeUtils.escapeJava("هولاء كومو")
This class is available on: Commons Lang from Apache
Hope this helps!
Check the HTTP Status Response Codes. An error happened on the server, so the diagnostics will need to be performed on the server, not on the client.

Java - Upload OutputStream as HTTP File Upload

I've got a legacy application that writes to an OutputStream, and I'd like to have the contents of this stream uploaded as a file to a Servlet. I've tested the Servlet, which uses commons-fileupload, using JMeter and it works just fine.
I would use Apache HttpClient, but it requires a File rather than just an output stream. I can't write a file locally; if there was some in-memory implementation of File perhaps that might work?
I've tried using HttpURLConnection (below) but the server responds with "MalformedStreamException: Stream ended unexpectedly".
URL url = new URL("http", "localhost", 8080, "/upload");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
String boundary = "---------------------------7d226f700d0";
connection.setRequestProperty("Content-Disposition", "form-data; name=\"file\"");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);
connection.setRequestProperty("Accept", "application/json");
connection.setRequestMethod("POST");
connection.setChunkedStreamingMode(0);
connection.connect();
OutputStream out = connection.getOutputStream();
byte[] boundaryBytes =("--" + boundary + "\r\n").getBytes();
out.write(boundaryBytes);
//App writes to outputstream here
out.write("\r\n".getBytes());
out.write(("--"+boundary+"--").getBytes());
out.write("\r\n".getBytes());
out.flush();
out.close();
connection.disconnect();
The PostMethod allows you to set a RequestEntity, which is an interface which you can implement. you just need to implement the RequestEntity.writeRequest method appropriately.
Or, if you want HttpClient to handle the multi-part stuff for you, you could use MultipartRequestEntity with a custom Part.

URL parameter encoding/receiving problem

I use the below code to send data to a servlet:
When encoding = "UTF-8" or "GBK", the data is received correctly.
But when encoding = "UTF-16", The receiver receives null. WHY??
The Sender:
URL url = new URL(notifyURL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=" + encoding);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("notify_id=" + URLEncoder.encode("123", encoding) + "&notify_type=" + URLEncoder.encode("any", encoding));
out.flush();
out.close();
connection.connect();
The receiver servlet:
log.info(request.getParameter("notify_type")); //print null
According to the Javadocs for URLEncoder, you should only use UTF-8 because other encodings may cause problems. They link directly to the W3C spec from the Javadocs.
You have 2 issues,
UTF-16 is not supported by lots of web servers. Some URLDecoder can only handle single byte encoding (ASCII, Latin-1) and UTF-8.
You are using mixed encoding if your default encoding is not UTF-16. UTF-8 and GBK are both ASCII compatible (ASCII is encoded as itself) so you can mix with ASCII but you can't do that with UTF-16.

Categories

Resources