Primavera RestTemplate HTTP Post con parámetros causa error 400 solicitud incorrecta

Posible duplicado ¿ Necesita ayuda en RestTemplate Post Request with Body Parameters? Y Spring RESTtemplate POST, pero estas respuestas no funcionan para mí
Intenté obtener token de acceso de Instagram API por Spring Android. La solicitud del documento de Instagram así:

 curl \-F 'client_id=CLIENT-ID' \ -F 'client_secret=CLIENT-SECRET' \ -F 'grant_type=authorization_code' \ -F 'redirect_uri=YOUR-REDIRECT-URI' \ -F 'code=CODE' \https://api.instagram.com/oauth/access_token 

Aquí está mi token de acceso a la solicitud (después de obtener el token de solicitud con éxito):

  MultiValueMap<String, String> mvm = new LinkedMultiValueMap<String, String>(); mvm.add("client_id", INSTAGRAM_CILENT_ID); mvm.add("client_secret", INSTAGRAM_SECRET); mvm.add("grant_type", "authorization_code"); mvm.add("redirect_uri", CALLBACKURL); mvm.add("code", requestToken); InstagramResult result = restTemplate .postForObject("https://api.instagram.com/oauth/access_token", mvm, InstagramResult .class); 

La clase de asignación de resultados:

 public class InstagramLogin { public String access_token; public InstagramUser user; } public class InstagramUser { public String id; public String username; public String full_name; public String profile_picture; } 

Y el resto de la plantilla:

  RestTemplate restTemplate = new RestTemplate(); final List<HttpMessageConverter<?>> listHttpMessageConverters = new ArrayList< HttpMessageConverter<?> >(); listHttpMessageConverters.add(new GsonHttpMessageConverter()); listHttpMessageConverters.add(new FormHttpMessageConverter()); listHttpMessageConverters.add(new StringHttpMessageConverter()); restTemplate.setMessageConverters(listHttpMessageConverters); 

Pero siempre obtengo 400 error de solicitud incorrecta. Aquí está mi rastro de la pila:

 04-03 09:32:45.366: W/RestTemplate(31709): POST request for "https://api.instagram.com/oauth/access_token" resulted in 400 (BAD REQUEST); invoking error handler 04-03 09:32:46.857: E//DefaultRequestRunner.java:138(31709): 09:32:46.862 Thread-32787 An exception occurred during request network execution :400 BAD REQUEST 04-03 09:32:46.857: E//DefaultRequestRunner.java:138(31709): org.springframework.web.client.HttpClientErrorException: 400 BAD REQUEST 04-03 09:32:46.857: E//DefaultRequestRunner.java:138(31709): at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:76) 04-03 09:32:46.857: E//DefaultRequestRunner.java:138(31709): at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:524) 04-03 09:32:46.857: E//DefaultRequestRunner.java:138(31709): at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:481) 04-03 09:32:46.857: E//DefaultRequestRunner.java:138(31709): at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439) 04-03 09:32:46.857: E//DefaultRequestRunner.java:138(31709): at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:317) 

P / s: Estoy seguramente mis valores de los parámetros son correctos, porque probé por curl y funcionó bien.

Un servidor a menudo devolverá un HTTP 400 si el tipo de contenido no es aceptable para una solicitud. El ejemplo de curl de instagram utiliza el parámetro -F que especifica los datos de post multipart:

 -F, --form CONTENT Specify HTTP multipart POST data (H) 

Por lo tanto, puede intentar establecer explícitamente el encabezado HTTP Content-type en su solicitud RestTemplate:

 HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(mvm, requestHeaders); ResponseEntity<InstagramResult> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, InstagramResult.class); InstagramResult result = response.getBody(); 

Como se mencionó anteriormente en los comentarios, una herramienta de proxy como fiddler puede ser realmente útil para la depuración. El desafío con esta situación es que usted está trabajando con SSL, por lo que estas herramientas no serán capaces de "ver" las comunicaciones cifradas sin configuración especial.

 HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(LINKEDIN_POST_URL); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); nameValuePairs.add(new BasicNameValuePair("grant_type", grant_type)); nameValuePairs.add(new BasicNameValuePair("code", code)); nameValuePairs.add(new BasicNameValuePair("redirect_uri", redirect_uri); nameValuePairs.add(new BasicNameValuePair("client_id", client_id)); nameValuePairs.add(new BasicNameValuePair("client_secret", client_secret)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = httpclient.execute(httppost); 

Y para convertir su respuesta a String. Puedes usar:

 EntityUtils.toString(response.getEntity()); 

Supongo que desea enviar una solicitud de publicación para cualquier objeto. Para ello se utiliza un DefaultHttpClient. HttpPost Objeto tomará la url como el argumento (sólo url no los parámetros). Los parámetros que desea enviar se pueden editar en el objeto BasicNameValuePair. El primer parámetro como el nombre del parámetro y el segundo sería su valor. Tan pronto como llame al método de ejecución, la respuesta vendrá en el objeto HttpResponse. Ahora tiene que convertir el objeto HttpResponse a Entity. Y desde Entity puede llamar al método EntityUtils.toString () para convertirlo en String. Supongo que esperas datos de json. Puede que tenga que asignar una clase correspondiente a ella para convertir los datos de json en el objeto de clase java.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.