티스토리 뷰

 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


댓글
댓글쓰기 폼