개요.
뷰와 스프링을 연동하던 중, 클라이언트에서 서버단으로 Http Post 방식으로 전송하는 와중에 content-type 을 두가지로 달리하고 해당 내용이 크롬 개발자도구에서 다르게 찍힘을 확인할 수 있었다. 동일한 request body 이지만 표현하는 방식이 다르기 때문에 서버단에서 처리하는 방식또한 달랐다. 그리고 그 결과를 바탕으로 해당 내용에 대해서 정리하기 위함이다.
+) content-type
- post/ put 메시지와 같이 body 에 데이터를 실어보낼때, 웹서버에서 현재 보내는 데이터의 형식이 무엇인지 알려주기 위함.
- 만약 content-type 이 맞지 않는다면 415 Unsupported Media Type 이라는 에러가 발생한다.
+) accept
현재 클라이언트가 특정한 데이터 형식으로 받을 수 있다고 웹서버에게 알려주기 위함. 웹 서버가 반드시 그 형식을 따를 필요는 없다.
기본적으로 axios 는 자바스크립트의 객체, object 를 JSON 으로 직렬화한다. 직렬화된 내용은 스프링의 HttpMessageConverter 가 적절히 처리하는데, HttpMessageConverter 내의 수 많은 구현중에서 MappingJackson2HttpMessageConverter 을 이용한다. 해당 컨버터는 내부적으로 ObjectMapper 를 구현하고 있으며 JSON 으로 들어오는 내용에 대해서 직렬화 및 역직렬화를 수행하고 있다. 이러한 매핑을 수행하기 위하여, 나는 항상 요청 본문을 받기위해 @RequestBody 라는 어노테이션을 사용하고 있다.
만약에 axios 를 이용하는 와중에 application / x-www-form-urlencoded 형식으로 데이터를 전송하고자 한다면 아래와 같이 사용하여야 한다.
const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));
[ Request Payload ]
☞ Vue Code
- request header, content-type : application/json
- request payload
payloadActions() {
const uri = '/test-api/req-payload';
const payload = {};
payload.name = 'payload-name';
payload.desc = 'payload-desc';
console.debug(payload);
return new Promise((resolve, reject) => {
request.post(uri, payload).then((response) => {
console.debug(response);
}).catch((error) => {
console.error(error.response);
})
});
},
☞ Spring Code
@PostMapping("/req-payload")
public ResponseEntity<Object> reqPayload(@RequestBody TestDto.PayloadRequest request) {
log.debug("payload name : {}", request.name);
log.debug("payload desc : {}", request.desc);
return ResponseEntity.ok().body("ok");
}
[ Form Data ]
☞ Vue Code
- request header, content-type : application/x-www-form-urlencoded
- form data
formDataActions() {
const uri = '/test-api/req-form';
const formData = qs.stringify({ 'name': 'payload-name-00', 'desc': 'payload-desc-00' });
console.debug(formData);
return new Promise((resolve, reject) => {
request.post(uri, formData).then((response) => {
console.debug(response);
}).catch((error) => {
console.error(error.response);
})
});
}
☞ Spring Code
@PostMapping("/req-form")
public ResponseEntity<Object> reqForm(HttpServletRequest request) {
log.debug("form-data name : {}", request.getParameter("name"));
log.debug("form-data desc : {}", request.getParameter("desc"));
return ResponseEntity.ok().body("ok");
}
결론
위의 request body 와 form data 모두 요청본문에 데이터를 담고있지만 그 담고있는 데이터를 표현하는 방식은 크롬 개발자 도구로 보았을 때 전혀 다른 모양을 띄고 있다. 또한 추가적으로 브라우저 콘솔로 확인해보았을 때도 찍히는 내용도 상이하다. 결국 요청 본문이 어떠한 content-type 유형에 속하는지 파악하고 이에 대응하기 위해 서버단에서 어떻게 데이터를 받을 것인지에 대해서 고민해보아야 할 것이다.
크롬 개발자도구 상에서 찍힌 요청 본문의 데이터.
▶ request payload
▶ form data
참고링크
'Spring' 카테고리의 다른 글
20200328 [redis & springboot] 레디스를 이용한 세션 클러스터링. (수정 : 2020-09-24) (0) | 2020.03.28 |
---|---|
20180304 @RequestMapping 에 대한 이해. (수정 2020-08-17) (2) | 2020.03.25 |
20190925 ObjectMapper 싱글톤 설정 및 LocalDateTime 과의 관계. (0) | 2019.09.25 |
20190901 [환경설정] application.yml 설정 및 내용정리. (0) | 2019.09.01 |
20190826 리버스 프록시 & nginx 이용 무중단배포 [여러가지 용어들] (0) | 2019.08.26 |