📘 HttpServlet 정리 - 요청/응답 방식과 한계

웹 개발에서 HttpServlet은 클라이언트 요청을 처리하고, 적절한 응답을 돌려주는 기본적인 서블릿 기반 기술입니다. 이 문서에서는 요청 처리 방식(GET, POST, JSON)과 응답 방식(HTML, TEXT, JSON), 그리고 서블릿 방식의 한계점까지 정리합니다.

 

 

📥 요청 데이터 처리

HTTP 요청 메시지를 개발자가 직접 파싱할 수도 있지만, 매우 불편하고 오류가 발생하기 쉽습니다. Servlet은 이를 대신 처리하여 HttpServletRequest 객체에 파싱된 정보를 담아 제공합니다.

 

1. 쿼리 파라미터 (GET 요청에서만 사용 가능)

GET 방식에서는 URL에 ?key=value 형태로 데이터를 전송하며, HttpServletRequest.getParameter() 메서드를 통해 해당 데이터를 읽을 수 있습니다.

GET /hello?name=kim&age=25
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String name = req.getParameter("name"); // "kim"
    String age = req.getParameter("age");   // "25"
}
  • 장점: 간단한 정보 전달에 적합합니다.
  • 단점: 길이 제한이 있으며, 보안에 취약한 정보를 전송하기에 부적절합니다.

 

2. Form 데이터 (POST 요청에서만 사용 가능)

HTML <form> 태그를 통해 application/x-www-form-urlencoded 방식으로 전송된 데이터도 getParameter()로 읽을 수 있습니다.

<form method="POST" action="/login">
  <input type="text" name="email">
  <input type="password" name="password">
</form>
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String email = req.getParameter("email");
    String password = req.getParameter("password");
}
  • 장점: GET보다 많은 양의 데이터를 보낼 수 있습니다.
  • 단점: 파일 업로드나 JSON 데이터는 별도의 처리가 필요합니다.

 

3. JSON 등 API 요청 데이터 (body 직접 파싱)

SPA 또는 모바일 앱에서는 JSON 형식으로 데이터를 전송하는 경우가 많습니다. 이 경우에는 getReader()를 이용하여 직접 요청 본문을 읽어야 합니다.

// 프론트엔드 예시
fetch('/api/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'test@example.com', password: '1234' })
});
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    BufferedReader reader = req.getReader();
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        sb.append(line);
    }
    String json = sb.toString();
    // Jackson 등의 라이브러리로 파싱 필요
}
  • 장점: 구조화된 데이터를 쉽게 전달할 수 있습니다.
  • 단점: 직접 파싱해야 하며, 보통 Jackson, Gson 등 라이브러리가 필요합니다.

 

 

📤 응답 데이터 처리

응답은 HttpServletResponse를 통해 클라이언트에게 전송하며, MIME 타입에 따라 HTML, 텍스트, JSON 등 다양한 형식으로 보낼 수 있습니다.

 

1. HTML 응답

resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><body><h1>Hello</h1></body></html>");
  • 용도: 전통적인 JSP/서블릿 방식의 웹 페이지 응답

 

2. Plain Text 응답

resp.setContentType("text/plain;charset=UTF-8");
resp.getWriter().println("Hello, plain text!");
  • 용도: 간단한 메시지, 상태 응답

 

3. JSON 응답

resp.setContentType("application/json;charset=UTF-8");
resp.getWriter().println("{\\"result\\": \\"success\\", \\"user\\": \\"kim\\"}");

실제 개발에서는 Jackson을 사용하는 것이 안전합니다.

ObjectMapper mapper = new ObjectMapper();
Map<String, String> data = Map.of("result", "success", "user", "kim");
String json = mapper.writeValueAsString(data);

resp.setContentType("application/json;charset=UTF-8");
resp.getWriter().write(json);
  • 용도: API 서버 응답 형식으로 가장 많이 사용됩니다.

 

 

HttpServlet 방식의 한계

한계점 설명
반복 코드가 많습니다 파라미터 추출, JSON 파싱, 응답 처리 등을 직접 구현해야 합니다.
테스트가 어렵습니다 서블릿 테스트는 별도 환경 설정과 Mock이 필요합니다.
유지보수가 어렵습니다 요청과 응답을 하나의 클래스에서 모두 처리하며 규모가 커질수록 복잡해집니다.
생산성이 낮습니다 Spring MVC에 비해 개발 속도가 느리며, 구조화가 어렵습니다.
확장성이 부족합니다 필터, 인터셉터, 예외 처리 등을 일일이 구현해야 합니다.

 

HttpServlet은 웹 서버 프로그래밍의 기본이지만, 실무에서는 Spring MVC와 같은 프레임워크가 이를 훨씬 효율적으로 대체하고 있습니다.

개발자 성현