TeampUp API를 사용하면서 Header에 Access Token을 실어서 함께 POST로 JSON을 보내야 했습니다. 먼저 RestTemplate에 MappingJackson2HttpMessageConverter를 설정하고 MultiValueMap에 데이터를 입력 후 ContentType을 application/json으로 설정한 뒤 요청을 했더니 HTTP 400 에러가 발생했습니다. API에 의하면 Bad Request (요청 데이터, 파라미터 오류)였습니다. MappingJackson2HttpMessageConverter에서 Map을 JSON으로 컨버트 해주는지 알았는데 아니였습니다.
정리를 할겸 ContentType에 따른 데이터의 연관성을 간단하게 테스트를 해보았습니다.
<Body Test case>
JSON String - JSONObject를 이용하여 json String 사용 ex) "{ \"a\" : \"b\"}"
MultiValueMap - Map 형태
POJO - 객체 형태
<ContentType Test case>
multipart/form-data - 우연히 바꿔보다 성공을 해서 궁금해서 테스트에 추가.
application/x-www-form-urlencoded - MultiValueMap을 지원하므로 추가.
application/json - JSON을 보내고 싶은 것이므로 추가.
세 가지 경우를 위한 RestTemplate MessageConverter 설정.
1 2 3 | HttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter(); StringHttpMessageConverter stringMessageConverter = new StringHttpMessageConverter( Charset.forName( "UTF-8" ) ); MappingJackson2HttpMessageConverter jackson2Converter = new MappingJackson2HttpMessageConverter(); | cs |
테스트 결과 :
multipart/form-data과 application/x-www-form-urlencoded에서 JSON String은 MessageConverter에서 가공되지 않고 이미 가공된 형태의 JSON이 된 것 같은 효과로 성공을 거두는 것이라고 생각됩니다. FormHttpMessageConverter에서 객체에 대한 컨버트를 지원하지 않는 것을 볼 수 있습니다. multipart/form-data는 주로 파일을 다룰 때 쓰고 있습니다. 그렇기때문에 FormHttpMessageConverter에서 Map<String, Object>를 컨버팅해주게 되어 Map<String, String>을 컨버팅해주는 application/x-www-form-urlencoded와는 다른 결과가 발생하게 됩니다.
application/x-www-form-urlencoded의 MultiValueMap에서 406 Not Acceptable (JSON 데이터 오류)가 발생하는 것은 컨버트된 데이터의 형태가 { "content" : "value" } 형태를 원하는 구조에 맞지 않고 value에 배열이 쌓여진다든지의 형태 변환이 있을 것 같습니다. 정확한 이해를 하기 위해 피들러나 각종 툴을 사용해서 정확한 원인을 분석해야될 것 같습니다!
마지막으로 application/json에서 MappingJackson2HttpMessageConverter가 POJO 객체를 JSON 형태로 작성하여 성공되는 것을 볼 수 있습니다.
결론적으로 RestTemplate를 이용하여 Header와 JSON을 보내는 최종 형태는 이렇게 작성하였습니다.
1 2 3 4 5 6 7 8 9 | ContentRequest contentRequest = new ContentRequest(); contentRequest.setContent("----"); HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "bearer " + token); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity requestEntity = new HttpEntity ( contentRequest, headers); restOperations.exchange(sendUrl, HttpMethod.POST, requestEntity, SendResponse.class); | cs |
'개발 > Spring' 카테고리의 다른 글
(1) 스프링, isomorphic, 서버사이드 렌더링 (0) | 2016.09.13 |
---|---|
스프링 부트, YAML 적용 (3) | 2016.06.25 |
스프링 부트에서 구글 API 연동 (2) Calendar API 사용하기 (1) | 2016.06.22 |
스프링 부트에서 구글 API 연동 (1) 설정부터 Oauth 인증 (2) | 2016.06.21 |
스프링 RestTemplate Response XML (3) | 2016.04.10 |
댓글