복붙노트

[SPRING] Spring RestTemplate 매개 변수가있는 HTTP Post에서 400 개의 잘못된 요청 오류가 발생합니다.

SPRING

Spring RestTemplate 매개 변수가있는 HTTP Post에서 400 개의 잘못된 요청 오류가 발생합니다.

가능한 복제 바디 매개 변수가있는 RestTemplate 포스트 요청에 대한 도움이 필요하십니까? 및 봄 RESTtemplate POST하지만 이러한 대답은 나를 위해 작동하지 않습니다. 나는 스프링 안드로이드에 의해 Instagram API로부터 액세스 토큰을 얻으려고했다. Instagram의 문서 요청은 다음과 같습니다 :

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 : 컬링 테스트를했기 때문에 매개 변수 값이 정확합니다.

해결법

  1. ==============================

    1.컨텐츠 유형이 요청에 대해 수용 가능하지 않은 경우, 서버는 종종 HTTP 400을 리턴합니다. instagram의 컬 (curl) 예제는 멀티 파트 포스트 데이터를 지정하는 -F 매개 변수를 사용합니다.

    컨텐츠 유형이 요청에 대해 수용 가능하지 않은 경우, 서버는 종종 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을 사용하여 작업 중이므로 특별한 구성없이 암호화 된 통신을 "볼"수 없기 때문입니다.

  2. ==============================

    2.

    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 Object는 url을 인수로 취합니다 (url은 매개 변수가 아닙니다). 보낼 매개 변수는 위에서 BasicNameValuePair 개체에서 편집 할 수 있습니다. 첫 번째 매개 변수는 매개 변수의 이름이고 두 번째 매개 변수의 값입니다. execute 메소드를 호출하자마자 응답이 HttpResponse 객체에 올 것이다. 이제 HttpResponse 객체를 Entity로 변환해야합니다. 그리고 Entity에서 EntityUtils.toString () 메서드를 호출하여 String으로 변환 할 수 있습니다. 나는 당신이 json 데이터를 기대하고 있다고 가정합니다. json 데이터를 Java 클래스 객체로 변환하려면 해당 클래스를 매핑해야 할 수도 있습니다.

  3. from https://stackoverflow.com/questions/22826887/spring-resttemplate-http-post-with-parameters-cause-400-bad-request-error by cc-by-sa and MIT license