Frühling RestTemplate HTTP Post mit Parametern Ursache 400 Bad Request Fehler

? R4j @ | Original: StackOverFlow
---

mögliche doppelte http://stackoverflow.com/questions/12202729/need-help-on-resttemplate-post-request-with-body-parameters und http://stackoverflow.com/questions/20557326/spring-resttemplate-post aber diese Antworten nicht für mich arbeiten Ich habe versucht, Zugriffstoken von Instagram API von Spring Android zu bekommen. Der Antrag http://instagram.com/developer/authentication/ wie folgt aus:

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

Hier ist mein Wunsch Zugriffstoken ( Nachdem ich Anforderung-Token erfolgreich) :

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

Das Ergebnis Mapping -Klasse :

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

Und der Rest Vorlage :

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

Aber ich bekomme immer 400 Bad Request Fehler. Hier ist mein Stack-Trace :

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 : Ich bin sicher meine Parameterwerte richtig sind, weil ich getestet von Locke und es funktionierte gut .

---

Top 5 Antwort

1Roy Clarkson @

Ein Server wird häufig zurückkehren, einen HTTP- 400, wenn der Inhaltstyp ist nicht für einen Antrag zulässig. Der Curl Beispiel aus instagram verwendet den Parameter -F, die mehrteiligen Beitrag Daten angibt :

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

Daher sollten Sie explizit versuchen Sie, den HTTP-Header Content-Type in Ihrem RestTemplate Anfrage:

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

Wie bereits in den Kommentaren erwähnt, kann ein Proxy- Tool wie Fiddler wirklich nützlich für die Fehlersuche sein . Die Herausforderung, mit dieser Situation ist, dass Sie mit SSL arbeitet, so werden diese nicht in der Lage zu "sehen" die verschlüsselte Kommunikation ohne besondere Konfiguration sein.

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

Und um Ihre Reaktion auf String zu konvertieren. Sie können:

EntityUtils.toString(response.getEntity());

Ich nehme an, Sie ein Gesuch für ein beliebiges Objekt gesendet werden soll. Dazu ist ein DefaultHttpClient verwendet. Httppost Objekt wird die URL als Argument (nur url nicht die Parameter ) zu nehmen. Die Parameter, die Sie senden möchten, können oben in BasicNameValuePair Objekt bearbeitet werden. Der erste Parameter, wie der Name des Parameters und die zweite würde seinen Wert. Sobald Sie die Methode execute rufen die Antwort wird in der Httpresponse- Objekt zu kommen. Sie haben nun die Httpresponse-Objekt zu Entity umzuwandeln. Und von Entity können Sie EntityUtils.toString () -Methode aufrufen, um den String zu konvertieren. Ich nehme an, Sie erwarten eine JSON- Daten sind . Möglicherweise müssen Sie eine Klasse entsprechend darauf Karte, um JSON -Daten zu Java-Klasse -Objekt zu konvertieren .