HTTP request 요청 시 Content-Type의 중요성
HTTP POST 방식으로의 Request 요청 시 서블릿에서 getParameter("data")를 이용하여 데이터를 뽑아 올 때 주의사항이 있다.
내가 삽질했던 내용을 적어보면 다음과 같다.
서버 코드의 Controller에 다음의 request handler mapping이 정의되어 있다.
@RequestMapping(value = "/test", method = RequestMethod.POST)
@ResponseBody
public String test(HttpServletRequest request) {
String reqData = request.getParameter("data");
return "success";
}
위에 작성되어 있는 handler가 정상 동작하는지에 대해서 테스트 코드를 작성한 후 HTTP POST 요청을 날렸다.
서버에서 요청은 잘 받지만 request.getParameter("data") 의 값은 null이 찍힌다.
이상한 것은 다음의 html 코드를 생성한 후 브라우저에서 호출을 하면 request.getParameter("data") 의 값이 "11111111"로 찍히는 것이다.
<body onload="document.test.submit();">
<form method="POST" name="test" action="http://localhost:8080/test">
<input type="hidden" name="data" id="data" value="11111111">
</form>
</body>
테스트 코드를 이용한 방식으로의 요청 시 왜 서버 코드의 getParameter("data")로 데이터 추출이 불가능한가 싶어 네트워크 캡쳐까지 해봤는데 정상적으로 HTTP request body에 데이터를 실어서 전송하고 있다.
이상한 생각에 body데이터를 stream을 이용해 읽어 보니 body에는 데이터가 존재한다.
String reqData = HttpUtil.readStream(request.getInputStream());
결론은 Content-Type 으로 인한 문제였다.
테스트 코드를 이용한 HTTP request 요청 시의 Content-Type은 text/plain 이였고, 브라우저를 이용한 테스트 시에는 application/x-www-form-urlencoded 를 서버에 전달했다.
application/x-www-form-urlencoded 컨텐츠 타입에 대해서 알아보면 key=value&key=value 와 같은 데이터를 전달한다라고 규약이 되어 있다.
즉, 서블릿 컨테이너는 컨텐츠 타입이 application/x-www-form-urlencoded 이면 request의 body를 읽어 Map 형태로 변환한다. 그렇게 때문에 request.getParameter 와 같은 형태로 데이터를 읽어 들일 수 있는 것이다.
application/x-www-form-urlencoded 헤더 타입이면서 HTTP POST 요청 시
-> getParameter("data") 와 같은 방법으로 추출 가능
text/plain 헤더 타입이면서 HTTP POST 요청 시
-> getParameter("data") 와 같은 방법으로 데이터 추출 불가능
-> request body를 stream을 이용하여 읽어와야 함.
request.getParameter("data"); 와 같은 방식으로의 데이터 추출 방법은 최근 많이 사용되고 있지 않지만 궁금한 마음에 정리해 본다.
'프로그래밍' 카테고리의 다른 글
Servlet의 request, response와 JSP의 request, response는 서로 다른 객체 (0) | 2015.07.23 |
---|---|
SimpleDateFormat 쓰레드 세이프 하지 않음 (0) | 2015.07.02 |
mybatis multiple select key (2) | 2015.05.21 |
iframe사이트와 parent사이트간 메세지 전송 방법 (서로 도메인이 다른 경우) (0) | 2015.05.21 |
@InitBinder를 이용한 사용자 로그인 정보 @ModelAttribute 객체에 저장하기 (0) | 2015.03.04 |
@Async 사용 시 spring security 세션 정보 추출 주의사항 (0) | 2015.03.04 |
@RequestMapping value에 property values 주입하기 (0) | 2014.12.05 |
Free Java Hotswap DCEVM (3) | 2014.09.01 |