template postforobject error code catch java android spring spring-android

java - postforobject - Spring RestTemplate HTTP Post con parámetros causa 400 error de solicitud incorrecta



resttemplate get status code (2)

Posible duplicado ¿ Necesita ayuda con RestTemplate Post Request with Body Parameters? y Spring RESTtemplate POST, pero estas respuestas no funcionan para mí
Intenté obtener el token de acceso desde la API de Instagram de Spring Android. La solicitud del documento de Instagram es la siguiente:

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 de solicitud (Después de recibir el token de solicitud correctamente)

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 mapeo 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 recibo 400 errores de solicitud errónea. Aquí está mi rastro de 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 seguro de que mis valores de parámetros son correctos, porque lo probé con 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 rizo de instagram usa el parámetro -F que especifica los datos de publicación de varias partes:

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

Por lo tanto, es posible que desee intentar establecer explícitamente el encabezado HTTP de tipo de contenido 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 proxy como fiddler puede ser realmente útil para la depuración. El desafío con esta situación es que está trabajando con SSL, por lo que estas herramientas no podrán "ver" las comunicaciones cifradas sin una 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 tu respuesta a String. Puedes usar:

EntityUtils.toString(response.getEntity());

Supongo que desea enviar una solicitud de publicación para cualquier objeto. Para eso se utiliza un DefaultHttpClient. El objeto HttpPost tomará la url como argumento (solo la url no los parámetros). Los parámetros que desea enviar se pueden editar arriba 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 tienes que convertir el objeto HttpResponse a Entidad. Y desde Entity puedes llamar al método EntityUtils.toString () para convertir a String. Supongo que estás esperando un dato json. Es posible que tenga que asignar una clase correspondiente para convertir los datos json en objetos de clase java.