可能重复Need help on RestTemplate Post Request with Body Parameters?和Spring RESTtemplate POST,但这些答案对我不起作用
我试图通过Spring Android从Instagram
API获取访问令牌。来自Instagram 's document的请求是这样的:
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
这是我的请求访问令牌(在我获得请求令牌成功后):
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);
结果映射类:
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;
}
其余模板:
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);
但我总是得到400个错误请求错误。这是我的堆栈跟踪:
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:我肯定是我的参数值是正确的,因为我通过curl测试它运行良好。
答案 0 :(得分:27)
如果请求的内容类型不可接受,服务器通常会返回HTTP 400。来自instagram的curl示例使用-F
参数指定多部分发布数据:
-F, --form CONTENT Specify HTTP multipart POST data (H)
因此,您可能希望尝试在RestTemplate请求中显式设置Content-type HTTP标头:
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();
正如前面评论中所提到的,像fiddler这样的代理工具对调试非常有用。这种情况的挑战在于您正在使用SSL,因此这些工具无法看到&#34;&#34;没有特殊配置的加密通信。
答案 1 :(得分:1)
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);
并将您的回复转换为String。您可以使用:
EntityUtils.toString(response.getEntity());
我想你想发送任何对象的帖子请求。为此,使用DefaultHttpClient。 HttpPost对象将以url作为参数(仅url不是参数)。 您可以在BasicNameValuePair对象中上面编辑要发送的参数。第一个参数作为参数的名称,第二个参数是其值。 一旦调用execute方法,响应就会出现在HttpResponse对象中。 您现在必须将HttpResponse对象转换为Entity。从Entity,您可以调用EntityUtils.toString()方法转换为String。我想你期待一个json数据。您可能必须映射与其对应的类以将json数据转换为java类对象。