HttpServletRequest의 파라미터를 읽기 위해, 아래와 같이 getParameterMap() 메서드를 사용하여 파라미터를 로그에 찍었다.
getParameterMap()Map<String, String[]> paramMap = request.getParameterMap();
for (Iterator it = paramMap.keySet().iterator(); it.hasNext();) {
String key = it.next().toString();
String[] values = paramMap.get(key);
log.debug("######## param [key],[values]=> [{}],{}", key, values);
}
그런데 contentType이 application/json인 경우, 로그에 찍히는게 없었다.
구글링을 해보니, request를 읽어들이는 방법은 아래와 같이 3가지가 존재한다.
getInputStream()getReader()getParameter()그 중에서 3번째 getParameter() 메서드는 getParameter Family라고 아래와 같이 4가지 메서드가 존재한다. 모두 Map 형태로 결과를 반환한다.
getParameter()getParameterNames()getParmeterValues()getParameterMap()해당 메서드들이 Map을 생성할 때 조건이 있는데,
1. 요청은 Http/Https
2. Http method는 POST
3. Content-type은 application/x-www-form-urlencoded
4. getParameter family 메서드 중에서 처음 호출호출 되었을때만 생성한다.
5. 조건이 충족되지 않으면 Map을 생성하지 않는다. 이때 Map 생성 시 InputStream을 생성해서 만들기 때문에, 4와 같은 조건이 생긴 것이다.
(또한, HttpServletRequest.getInputStream() 도 사용이 불가해진다.)
그래서 content-type이 'application/json'인 경우,
request의 파라미터를 읽을때 request.getInputStream() 를 사용해야 한다.
public static String getrequestBody(HttpServletRequest request) throws IOException {
String reqStr = null;
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
reqStr = stringBuilder.toString();
return reqStr;
}