Solicitud POST enviar datos json java HttpUrlConnection

Desarrollé un código java que convierte el siguiente cURL en código java usando URL y HttpUrlConnection. el rizo es:

curl -i 'http://url.com' -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{"auth": { "passwordCredentials": {"username": "adm", "password": "pwd"},"tenantName":"adm"}}' 

He escrito este código pero siempre da una solicitud incorrecta al código HTTP 400. No pude encontrar lo que falta.

 String url="http://url.com"; URL object=new URL(url); HttpURLConnection con = (HttpURLConnection) object.openConnection(); con.setDoOutput(true); con.setDoInput(true); con.setRequestProperty("Content-Type", "application/json"); con.setRequestProperty("Accept", "application/json"); con.setRequestMethod("POST"); JSONObject cred = new JSONObject(); JSONObject auth = new JSONObject(); JSONObject parent = new JSONObject(); cred.put("username","adm"); cred.put("password", "pwd"); auth.put("tenantName", "adm"); auth.put("passwordCredentials", cred.toString()); parent.put("auth", auth.toString()); OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream()); wr.write(parent.toString()); wr.flush(); //display what returns the POST request StringBuilder sb = new StringBuilder(); int HttpResult = con.getResponseCode(); if (HttpResult == HttpURLConnection.HTTP_OK) { BufferedReader br = new BufferedReader( new InputStreamReader(con.getInputStream(), "utf-8")); String line = null; while ((line = br.readLine()) != null) { sb.append(line + "\n"); } br.close(); System.out.println("" + sb.toString()); } else { System.out.println(con.getResponseMessage()); } 

Tu JSON no es correcto. En lugar de

 JSONObject cred = new JSONObject(); JSONObject auth=new JSONObject(); JSONObject parent=new JSONObject(); cred.put("username","adm"); cred.put("password", "pwd"); auth.put("tenantName", "adm"); auth.put("passwordCredentials", cred.toString()); // <-- toString() parent.put("auth", auth.toString()); // <-- toString() OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream()); wr.write(parent.toString()); 

escribir

 JSONObject cred = new JSONObject(); JSONObject auth=new JSONObject(); JSONObject parent=new JSONObject(); cred.put("username","adm"); cred.put("password", "pwd"); auth.put("tenantName", "adm"); auth.put("passwordCredentials", cred); parent.put("auth", auth); OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream()); wr.write(parent.toString()); 

Por lo tanto, JSONObject.toString () debe invocarse solo una vez para el objeto externo.

Otra cosa (probablemente no sea su problema, pero me gustaría mencionarlo):

Para asegurarse de no tener problemas de encoding, debe especificar la encoding, si no es UTF-8 :

 con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); con.setRequestProperty("Accept", "application/json"); // ... OutputStream os = con.getOutputStream(); os.write(parent.toString().getBytes("UTF-8")); os.close(); 
 private JSONObject uploadToServer() throws IOException, JSONException { String query = "https://example.com"; String json = "{\"key\":1}"; URL url = new URL(query); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); OutputStream os = conn.getOutputStream(); os.write(json.getBytes("UTF-8")); os.close(); // read the response InputStream in = new BufferedInputStream(conn.getInputStream()); String result = org.apache.commons.io.IOUtils.toString(in, "UTF-8"); JSONObject jsonObject = new JSONObject(result); in.close(); conn.disconnect(); return jsonObject; } 

Puede usar este código para conectarse y solicitar el uso de http y json

 try { URL url = new URL("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet" + "&key=AIzaSyAhONZJpMCBqCfQjFUj21cR2klf6JWbVSo" + "&access_token=" + access_token); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json"); String input = "{ \"snippet\": {\"playlistId\": \"WL\",\"resourceId\": {\"videoId\": \""+videoId+"\",\"kind\": \"youtube#video\"},\"position\": 0}}"; OutputStream os = conn.getOutputStream(); os.write(input.getBytes()); os.flush(); if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) { throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode()); } BufferedReader br = new BufferedReader(new InputStreamReader( (conn.getInputStream()))); String output; System.out.println("Output from Server .... \n"); while ((output = br.readLine()) != null) { System.out.println(output); } conn.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 

la respuesta correcta es buena, pero

 OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream()); wr.write(parent.toString()); 

no funciona para mí , en lugar de usarlo :

 byte[] outputBytes = rootJsonObject.getBytes("UTF-8"); OutputStream os = con.getOutputStream(); os.write(outputBytes); 

Tuve un problema similar, obtenía 400, solicitud incorrecta solo con el PUT, donde la solicitud POST estaba perfectamente bien.

El código siguiente funcionaba bien para POST, pero estaba dando BAD Request for PUT:

 conn.setRequestProperty("Content-Type", "application/json"); os.writeBytes(json); 

Después de realizar los cambios a continuación, funcionó bien tanto para POST como para PUT

 conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); os.write(json.getBytes("UTF-8"));