Printemps RestTemplate HTTP Post avec les paramètres de provoquer 400 bad request error

double Besoin d'aide sur RestTemplate Requête Post avec le Corps de Paramètres? et Spring RESTtemplate POST mais ces réponses ne fonctionne pas pour moi

j'ai essayé d'obtenir un jeton d'accès à partir de Instagram API d'ici le Printemps Android. La demande de Instagram ' S document comme ceci:

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

Voici mon token d'accès à la requête (après que j'ai réussi à obtenir le token de la requête):

 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 cartographie des résultats classe:

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

Et le reste modèle:

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

mais j'ai toujours 400 erreurs de mauvaise requête. Voici ma trace 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: je suis sûr que mes valeurs de paramètre sont correctes, parce que j'ai testé par curl et ça a bien fonctionné.

19
demandé sur Community 2014-04-03 06:45:06

2 réponses

un serveur renvoie souvent un HTTP 400 si le type de contenu n'est pas acceptable pour une requête. L'exemple curl d'instagram utilise le -F paramètre qui spécifie les données de post multipart:

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

par conséquent, vous pouvez essayer de définir explicitement L'en-tête HTTP de type Content dans votre requête 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();

comme mentionné plus haut dans les commentaires, un outil de proxy comme fiddler peut être très utile pour le débogage. Le défi de cette situation est que vous travaillez avec SSL, donc ces outils ne pourront pas "voir" les communications cryptées sans configuration spéciale.

27
répondu Roy Clarkson 2014-04-03 16:34:29
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);

et de convertir votre réponse en chaîne. Vous pouvez utiliser:

EntityUtils.toString(response.getEntity());

je suppose que vous voulez envoyer une requête post pour n'importe quel objet. Pour cela on utilise un DefaultHttpClient. L'objet HttpPost prendra l'url comme argument (seulement l'url et non les paramètres). Les paramètres que vous voulez envoyer peuvent être édités ci-dessus dans L'objet BasicNameValuePair. Premier paramètre le nom du paramètre et la deuxième serait sa valeur. Dès que vous appelez la méthode execute la réponse viendra dans L'objet HttpResponse. Vous devez maintenant convertir L'objet HttpResponse en Entity. Et de Entity vous pouvez appeler EntityUtils.méthode toString() pour convertir en Chaîne. Je suppose que vous attendez un JSON data. Vous pourriez avoir à mapper une classe correspondant à elle pour convertir des données json en objet de classe java.

1
répondu Aarambh 2014-11-18 12:02:07