출처: http://lng1982.tistory.com/225
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"); 와 같은 방식으로의 데이터 추출 방법은 최근 많이 사용되고 있지 않지만 궁금한 마음에 정리해 본다.
'IT_Programming > Java' 카테고리의 다른 글
[펌] Java 병렬 프로그래밍 Summary (0) | 2013.09.14 |
---|---|
HTTP multipart/form-data raw 데이터는 어떤 형태일까? (0) | 2013.08.01 |
Java theory and practice: : 클로저(closure) 논의 (0) | 2013.07.27 |
jsoup: Java HTML Parser (0) | 2013.07.21 |
[펌] 파일 감시 데몬 만들기 (0) | 2013.06.27 |