Spring RestTemplate HTTP Post with parameters cause 400 bad request error
可能重复是否需要有关带有正文参数的RestTemplate发布请求的帮助? 和Spring RESTtemplate POST,但这些答案对我不起作用
我试图通过Spring Android从
1 2 3 4 5 | 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 |
这是我的请求访问令牌(成功获取请求令牌后):
1 2 3 4 5 6 7 8 | 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); |
结果映射类:
1 2 3 4 5 6 7 8 9 10 11 |
其余模板:
1 2 3 4 5 6 7 | 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错误的请求错误。 这是我的堆栈跟踪:
1 2 3 4 5 6 7 8 | 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进行了测试,并且效果很好。
如果请求的内容类型不可接受,则服务器通常会返回HTTP 400。 instagram的curl示例使用
1 | -F, --form CONTENT Specify HTTP multipart POST data (H) |
因此,您可能想尝试在RestTemplate请求中显式设置Content-type HTTP标头:
1 2 3 4 5 | 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,因此如果没有特殊配置,这些工具将无法"查看"加密的通信。
1 2 3 4 5 6 7 8 9 10 11 12 | 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。您可以使用:
1 | EntityUtils.toString(response.getEntity()); |
我想您想发送任何对象的发布请求。为此,使用DefaultHttpClient。
HttpPost对象将url作为参数(仅url而不是参数)。
要发送的参数可以在BasicNameValuePair对象中进行编辑。第一个参数是参数的名称,第二个参数是其值。
一旦调用execute方法,响应就会出现在HttpResponse对象中。
现在,您必须将HttpResponse对象转换为Entity。从Entity可以调用EntityUtils.toString()方法转换为String。我想你期望一个json数据。您可能必须映射一个与其对应的类,才能将json数据转换为java类对象。