프론트로부터 request.getParameter를 통해 데이터를 받을 때, 데이터가 없는 경우가 있다. 이 때는 Form Data나 Body Message에 데이터가 담겨온 것인데, 이럴 경우 Stream을 이용해 parameter를 받아와야 한다.
보통 프론트 사이드에서 HttpRequest에 Parameter를 전송할 경우 Servlet에서 다음 함수로 받을 수 있다.

파라미터명을 아는 경우
request.grtParamrter(String param);
파라미터명을 모르는 경우
request.getParameterNames()

위 방식은 쿼리 스트링, 혹은 Form Data의 경우 정상적으로 받아지지만 Content-Type이 변하여(application/json 등) Body Content에 parameter가 담겨올 경우, 위 방식으로 Parameter를 찾아보면 null 값이 나온다.

이럴 경우 body content를 읽어들여야 하는데, request.getInputStream()을 이용해 buffer를 읽어들이면 된다.

StringBuilder stringBuilder = new StringBuilder(); // String Builder BufferedReader bufferedReader = null; try(InputStream inputStream = request.getInputStream()){ if(inputStream != null){ bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); char[] charBuffer = new char[256]; int bytesRead = -1; while ((bytesRead = bufferedReader.read(charBuffer)) > 0){ stringBuilder.append(charBuffer, 0, bytesRead); } } } catch (IOException e){ throw e; } finally { if(bufferedReader != null){ try{ bufferedReader.close(); }catch(IOException e){ throw e; } } }

이는 URL encoding 된 데이터를 가져오기 때문에 URL decoding 후 데이터를 사용하거나, 있는 그대로 사용해도 된다.


그러나 위 방식으로 parameter를 읽어올 경우, inputStream이 초기화되는 문제가 발생한다. (Tomcat은 inputStream을 읽는 순간 초기화된다.)

따라서 getInputStream으로 body는 모든 작업이 끝난 후 (적어도 내가 필요한 정보를 모두 확인했으나, body를 직접 읽어야 하는 경우)읽는게 좋다.

만약 request.getParameter()로 정상적인 parameter 접근이 가능하지만, request.getInputStream()으로 모두 읽어들인 후 request.getParameter()를 하면 null이 발생한다.


중간에 charBuffer 크기를 얼마나 할지 의문이 들 수 있는데, 넉넉하게 2^7 이상을 주거나, character형이 아닌 String형으로 한 line씩 읽어와도 된다.

... bufferedReader = new Bufferedreader(new InputStreamReader(inputStream)); String line; while((line = bufferedReader.readLine()) != null){ stringBuilder.append(line); } ...

+ Recent posts