Primavera RestTemplate HTTP Post con parametri causa 400 errore di richiesta male

? R4j @ | Original: StackOverFlow
---

Eventuali duplicati http://stackoverflow.com/questions/12202729/need-help-on-resttemplate-post-request-with-body-parameters e http://stackoverflow.com/questions/20557326/spring-resttemplate-post ma queste risposte non funzionano per me Ho cercato di ottenere il token di accesso da Instagram API entro la primavera Android . La richiesta da http://instagram.com/developer/authentication/ come questo:

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

Ecco il mio token di richiesta di accesso ( Dopo ho richiesta di token di successo ) :

 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 classe mappatura risultato :

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;
}

E il modello di riposo :

   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);

Ma ho sempre trovato 400 errori richiesta male . Ecco il mio stack :

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 : Sto sicuramente i miei valori dei parametri sono a destra, perché ho ​​provato da arricciare e ha funzionato bene .

---

Top 5 Risposta

1Roy Clarkson @

Un server spesso restituisce un HTTP 400 se il tipo di contenuto non è accettabile per una richiesta . L'esempio ricciolo dal instagram utilizza il parametro -F che specifica dati post multipart :

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

Pertanto, si consiglia di provare in modo esplicito impostare l'intestazione HTTP Content -type nella richiesta 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();

Come accennato in precedenza nei commenti, uno strumento di delega come violinista può essere davvero utile per il debug . La sfida di questa situazione è che si sta lavorando con SSL, in modo che questi strumenti non sarà in grado di " vedere" le comunicazioni criptate senza configurazione speciale .

2Aarambh @
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);

E per convertire la vostra risposta a stringa . È possibile utilizzare :

EntityUtils.toString(response.getEntity());

Suppongo che si desidera inviare una richiesta POST per qualsiasi oggetto . Per questo viene utilizzato un DefaultHttpClient . HttpPost Object prenderà l'url come argomento (solo non url dei parametri ) . I parametri che si desidera inviare possono essere modificati in precedenza in oggetto BasicNameValuePair . Primo parametro come il nome del parametro e seconda sarebbe il suo valore . Non appena si chiama il metodo execute la risposta arriverà nel Object HttpResponse . Ora è necessario convertire l'oggetto HttpResponse di Entity . E da Entity è possibile chiamare il metodo EntityUtils.toString ( ) per convertire in stringa . Suppongo che ci si aspetta un dato JSON . Potrebbe essere necessario associare una classe corrispondente ad esso per convertire i dati JSON all'oggetto classe Java .