HTTP POST Content Type Not Right - java

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.

Related

How to 'convert' a Java REST call to a Postman REST call

I'm having problems doing a Postman REST call copying a REST call in Java.
I tried to set request properties on Postman the same way they're set in Java, but it's not working.
I have to send a base64 string with this call (i put in italic the code line where this is done in Java code)
URLConnection connection = new URL(url + content).openConnection();
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setConnectTimeout(timeout);
((HttpURLConnection) connection).setRequestMethod("POST");
connection.setRequestProperty("Accept", "*/*");
connection.setRequestProperty("Connection", "keep-alive");
connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
OutputStream output = connection.getOutputStream();
JSONObject conf = new JSONObject();
conf.put("signedEvidence", String.format("%s", baos));
*output.write(conf.toString().getBytes());*
output.flush();
checkHttpStatus(connection);
I configured Postman like this:
And i receive this answer:
EDIT - In few words: the REST call works fine in Java, but i need to do some of these calls in Postman with my own variable (the service i'm calling do some works with base64 string i pass him).
EDIT2 - Main problem, in my opinion, is the line:
output.write(conf.toString().getBytes());
which set the base64 in my Java call, and i don't understand/know how to do the same in my Postman call.
Try only adding the following values:
Then, add the content type and the values which you need to pass.

Printing URLConnection request before sending

Java's URLConnection lets us form http requests. After forming a simple POST request like so:
URLConnection con = url.openConnection();
con.addRequestProperty("User-agent", "Mozilla");
con.setDoOutput(true);
String data = "text to send";
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(data);
Is there any way of checking what this request looks like before sending it?
You need to enable logging and in your logging.properties file you should have following property set
handlers= java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = FINEST
sun.net.www.protocol.http.HttpURLConnection.level=ALL
And, set the property file as a JVM property
-Djava.util.logging.config.file=logging.properties

How to set character encoding in SOAP request

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

Different behavior when sending POST Request through Java application and Chrome's POSTMAN Extension. How do I debug and find the mistake?

I am making a POST Request to a server with Content-Type set to application/x-www-form-urlencoded. One of the query parameter has a value which contains & in it. I replace the & with & before sending the request.
When I send this request using POSTMAN (Chrome Extension), the request goes fine and I receive the expected response. But when I send this request using a Java application, the server throws an error (unable to parse document). Here is the code that I'm using to send the request:
URL url = new URL(url); // url => "http://myserver.com/api/update"
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(60000);
urlConnection.setReadTimeout(60000);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter printWriter = new PrintWriter(urlConnection.getOutputStream());
printWriter.print(params); // params => api_key=abcd123&update_data_id=123&update_data_value=Test&Value
printWriter.flush();
InputStream inputStream = urlConnection.getInputStream();
String contentType = urlConnection.getContentType();
FileUtil.closeWriter(printWriter);
// Parse response ...
Here, the problem occurs in the parameter update_data_value. If I remove the &, the request goes fine from both, POSTMAN as well as my application. But when the & is present, only the request through POSTMAN works fine.
What could be wrong ?
Thanks a lot for your help!
After a long conversation in chat, the problem was this:
It's about a XML string, where an ampersand is used. The ampersand needs to replaced with "&", according to the XML-Standard.
This XML string needs to be sent in a POST request, so the ampersand and likely the semicolon need to be escaped.
The final replacement string looks like this: "%26amp%3B".

httpURLConnection: how long can a post argument be?

I'm currently using something like this:
HttpURLConnection con = (HttpURLConnection) u.openConnection ();
con.setDoInput(true);
con.setRequestMethod("POST");
con.setDoInput (true);
con.setDoOutput (true);
con.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded");
out = new DataOutputStream(con.getOutputStream());
String content = "username=" + URLEncoder.encode ("bob")
+ "&password=" + URLEncoder.encode ("smith");
System.out.println("\n" + "sending form to HTTP server ...");
out.writeBytes (content);
out.flush ();
out.close ();
con.connect();
With this I manage to pass some data to my server. What I'm wondering now is how much can be sent this way?
I want to be able to send some xml files (100-200 lines long) and would like to know if I can do this?
Jason
The post body (it's not usually called an argument, since that usually implies it being passed with the URL) can be any length, restricted only by configuration.
Since POST is used to implement file uploads, most systems allow pretty large bodies. 100-200 lines should not be a problem at all, except for the most paranoid configurations out there.
Any length, just keep in mind that your request can timeout. GET data is limited to 4096 bytes.
The maximum length of a post is usually configured in the server configuration, not on client-side.

Categories

Resources