Whole JSONObject sent as JSON key using HttpURLConnection in Android - java

I want to send a POST request to my NodeJS/Express API with some JSON data. I managed to make GET requests with no problem. Here's what I do for a POST request:
URL u = new URL(url);
JSONObject jsonObject = new JSONObject();
jsonObject.put("nombre", "testing");
c = (HttpURLConnection) u.openConnection();
c.setDoOutput(true);
c.setRequestMethod("POST");
c.setRequestProperty("Content-length", Integer.toString(URLEncoder.encode(jsonObject.toString(),"UTF-8").length()));
c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(0);
c.setReadTimeout(0);
c.connect();
DataOutputStream printout = new DataOutputStream(c.getOutputStream ());
printout.writeBytes(URLEncoder.encode(jsonObject.toString(),"UTF-8"));
printout.flush ();
printout.close ();
int status = c.getResponseCode();
In my API, I have a console.log(req.body); to see what is my POST route getting, and this is what I get in my console:
Got this for POST:
{ '{"nombre":"testing"}': '' }
The whole JSONObject is sent as the key for the JSON object with an empty value on the HTTP POST request. Any ideas on what am I doing wrong? Thanks!

Try replace
c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
with
c.setRequestProperty("Content-Type", "application/json");
and
printout.writeBytes(URLEncoder.encode(jsonObject.toString(),"UTF-8"));
with
printout.writeBytes(jsonObject.toString());

Related

Unable to make a post call using httpconnectionurl and outstreamwriter

Below is the code i am testing with. When i run this i see that post body is empty. i can see all my header when i trace on the server side but the body is empty. Can you please point out my mistake here ?
String jsonstring = "{\"id\":\"1233\", \"userName\" : \"jump2\"}";
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonstring);
System.out.println(jsonObject.toJSONString());
Long currentTime = System.currentTimeMillis();
URL restUrl = new URL("http://myservers.com/v1/register");
HttpURLConnection urlConnection = (HttpURLConnection) restUrl.openConnection();
urlConnection.addRequestProperty("X-CORRELATION-ID", currentTime.toString());
urlConnection.addRequestProperty("X-AUTH-APIKEY", "dDEdfaeFFDdddDF");
urlConnection.addRequestProperty("Accept","application/json");
urlConnection.addRequestProperty("Content-Type","application/json");
urlConnection.setDoOutput(true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8");
jsonObject.writeJSONString(outputStreamWriter);
System.out.println(urlConnection.getResponseCode());
System.out.println(urlConnection.getRequestMethod());
System.out.println(urlConnection.getContentEncoding());
outputStreamWriter.flush();
outputStreamWriter.close();
urlConnection.disconnect();```
You have to set Request method to POST
urlConnection.setRequestMethod("POST");
Example for HttpUrlConnection.

Java - HttpURLConnection PUT request with empty body

I'm trying make a request with Java, when I call it using cURL like this, it works:
curl -X PUT http://serverurl.com/method/6eb276a2-5c79-4f6e-a4b5-a26b0e6848c7/action -H 'Content-Type: application/json' -H 'Token: cba5f12c-af55-480f-970e-525e446ef153' -H 'Content-Length : 0'
If I call the same request without passing header Content-Length param, I get 411 HTTP error, length required.
This is my code in Java:
URL url = new URL("http://serverurl.com/method/6eb276a2-5c79-4f6e-a4b5-a26b0e6848c7/action");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("PUT");
con.addRequestProperty("Content-Type", "application/json");
con.addRequestProperty("Token", "cba5f12c-af55-480f-970e-525e446ef153");
con.connect();
This request is getting a 411 HTTP code response. So, I tryed to add:
con.addRequestProperty("Content-Length", "0");
But it doesn't work, so I changed to:
URL url = new URL("http://serverurl.com/method/6eb276a2-5c79-4f6e-a4b5-a26b0e6848c7/action");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("PUT");
con.addRequestProperty("Content-Type", "application/json");
con.addRequestProperty("Token", "cba5f12c-af55-480f-970e-525e446ef153");
con.setDoOutput(true);
con.getOutputStream().close();
con.setFixedLengthStreamingMode(0);
con.connect();
But now I'm getting 400 HTTP code.
How can I do a PUT request with an empty body and setting content length to match the cURL call?
using the HttpUrlConnection, you should use the setRequestProperty method to add headers to your request. I can see your using the "addRequestProperty" which is probably why its not working. But refer to this link for more info https://juffalow.com/java/how-to-send-http-get-post-request-in-java and heres some code that i use to for a put request
URL url = new URL(BASE_URL+"/"+userID+".json");
urlRequest = (HttpURLConnection) url.openConnection();
urlRequest.setDoOutput(true);
urlRequest.setRequestMethod("PUT");
urlRequest.setRequestProperty("Content-Type", "application/json;
charset=UTF-8");
OutputStream os = urlRequest.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
osw.write("{\"idToken\":\""+"token"+"\"}");
osw.flush();
osw.close();
urlRequest.connect();
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream)
urlRequest.getContent()));//Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject();//Maybe an array or object
well thats just sample what i use... and i hope this works for you. Happy coding.

POST request working fine with POSTMAN/Advance rest client while giving 400 error with HttpUrlConnection

I am a newbie to HttpClient so not sure what's wrong I am doing. I am hitting one POST request through HttpUrlConnection. After sending the request when I check the logs it doesn't hit the entire request. My URL is https://www.example.com/product/pd/v1/gql when I check on the server, for URI, it shows v1/gql and give 400 error. while the same request works perfectly from Postman and advance rest client.
URL obj = new URL("https://www.example.com/product/pd/v1/gql/");
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Cookie", "_bb_vid=djfhhf");
JSONObject val = new JSONObject(gqlValue2);
JSONObject jObj = new JSONObject();
jObj.put(gqlKey1, gqlValue1);
jObj.put(gqlKey2, val);
System.out.println(jObj);
OutputStreamWriter wr = new
OutputStreamWriter(conn.getOutputStream());
wr.write(jObj.toString());
wr.flush();

Android HttpsURLConnection and JSON for new GCM

I'm overhauling certain parts of my app to use the new GCM service to replace C2DM. I simply want to create the JSON request from a Java program for testing and then read the response. As of right now I can't find ANY formatting issues with my JSON request and the google server always return code 400, which indicates a problem with my JSON.
http://developer.android.com/guide/google/gcm/gcm.html#server
JSONObject obj = new JSONObject();
obj.put("collapse_key", "collapse key");
JSONObject data = new JSONObject();
data.put("info1", "info_1");
data.put("info2", "info 2");
data.put("info3", "info_3");
obj.put("data", data);
JSONArray ids = new JSONArray();
ids.add(REG_ID);
obj.put("registration_ids", ids);
System.out.println(obj.toJSONString());
I print my request to the eclipse console to check it's formatting
byte[] postData = obj.toJSONString().getBytes();
try{
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpsURLConnection.setDefaultHostnameVerifier(new JServerHostnameVerifier());
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key=" + API_KEY);
System.out.println(conn.toString());
OutputStream out = conn.getOutputStream();
// exception thrown right here. no InputStream to get
InputStream in = conn.getInputStream();
byte[] response = null;
out.write(postData);
out.close();
in.read(response);
JSONParser parser = new JSONParser();
String temp = new String(response);
JSONObject temp1 = (JSONObject) parser.parse(temp);
System.out.println(temp1.toJSONString());
int responseCode = conn.getResponseCode();
System.out.println(responseCode + "");
} catch(Exception e){
System.out.println("Exception thrown\n"+ e.getMessage());
}
}
I'm sure my API key is correct as that would result in error 401, so says the google documentation. This is my first time doing JSON but it's easy to understand because of its simplicity. Anyone have any ideas on why I always receive code 400?
update: I've tested the google server example classes provided with gcm so the problem MUST be with my code.
{"collapse_key":"new-test-notification","data":{"info1":"info_1","info3":"info_3","info2":"info 2"},"registration_ids":["APA91bG3bmCSltzQYl_yOcjG0LPcR1Qemwg7osYJxImpSuWZftmmIjUGH_CSDG3mswKuV3AAb8GSX7HChOKGAYHz1A_spJus5mXFtfOrK0fouBD7QBpKnfc_ly0t3S8vSYWRjuGxtXrt"]}
I solved it using a different approach so it must have been my original implementation.
List<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("username",username));
list.add(new BasicNameValuePair("deviceId",regId));
list.add(new BasicNameValuePair("deviceType","AndroidPhone"));
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("example.url.com");
post.setEntity(new UrlEncodedFormEntity(list));
ResponseHandler<String> handler = new BasicResponseHandler();
HttpResponse response = client.execute(post);
String responseString = handler.handleResponse(response);
JSONObject jsonResponse = new JSONObject(responseString);
I'm reading here that you should use your 'Key for browser apps'
GCM with PHP (Google Cloud Messaging) (in comments)
Try to reproduce the error using curl or another command-line tool so we can eliminate the possibility that there's a bug in your java that we're all missing.

POST from android to WCF Service (OData)

Edit:
After doing some more experimentation, I discovered that the request will only work if all of the values are quoted in the JSON string. That is to say that this won't work
{"Text":"test","RatingValue":0.0,"LocationID":5}
and this will
{"Text":"test","RatingValue":"0.0","LocationID":"5"}
What I don't understand is why. The first string seems to be a valid JSON string. Is this a quirk with WCF?
Original Post
I am trying to post a new item to a collection from android. I keep getting a response code of 400: Bad Request. I don't understand what I'm doing wrong and I was hoping someone might be able to help me. Here is the java code.
HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection();
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("User-Agent", userAgent);
conn.setChunkedStreamingMode(0);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(data.getBytes());
out.flush();
int code = conn.getResponseCode();
String message = conn.getResponseMessage();
conn.disconnect();
The data is a JSON string that looks like the following:
{"Text":"test","RatingValue":3.0,"ReviewID":0,"LocationID":5}
In this case the ReviewID is the primary key.
The URL for the request points to the collection of Ratings. If i paste the same location into my browser, it successfully queries the collection. It looks something like this:
http://localhost/DataService.svc/Ratings
try this :
HttpClient hc = new DefaultHttpClient();
HttpPost hp = new HttpPost("http://localhost/DataService.svc/Ratings");
HttpResponse hr;
JSONObject jo1 = new JSONObject();
joobject.put("Text", "test");
joobject.put("RatingValue", "3.0");
joobject.put("ReviewID", ".0");
joobject.put("LocationID", ".5");
StringEntity se = new StringEntity(joobject.toString(),HTTP.UTF_8);
se.setContentType("application/json");
hp.setEntity(se);
hr = hc.execute(hp);
maybe helpful

Categories