Servlet request-response cycle

Chap 1-2 서블릿 기초 정리

서블릿이란

Serve + Applet의 합성어로, HTTP 요청을 처리하는 작은 서버 측 프로그램이다.

상속 구조는 Servlet 인터페이스 → GenericServlet → HttpServlet → 커스텀 서블릿 순이다.

URL 매핑은 @WebServlet 어노테이션으로 처리한다.

@WebServlet(value = "/lifecycle", loadOnStartup = 1) public class LifeCycleTestServlet extends HttpServlet { ... }

loadOnStartup = 1을 설정하면 서버 시작 시 바로 인스턴스를 생성한다(기본값은 첫 요청 시 생성).


서블릿 라이프사이클

Tomcat은 서블릿 객체를 싱글톤으로 관리한다. 즉, 인스턴스는 딱 하나만 만들어진다.

1. 생성자 (Constructor)

최초 요청이 들어올 때 한 번만 호출된다.

2. init(ServletConfig config)

생성 직후 한 번만 호출된다. 초기화 작업(DB 연결, 설정 로드 등)을 여기서 한다.

3. service(ServletRequest req, ServletResponse resp)

요청이 올 때마다 호출된다. 내부적으로 HTTP 메서드를 판별해서 doGet(), doPost() 등을 분기 호출한다.

4. destroy()

Tomcat이 종료될 때 한 번만 호출된다. 리소스 해제 작업을 여기서 한다.

요청 → [생성자 → init] (최초 1회) → service (매 요청) → destroy (종료 시)

응답 출력

resp.getWriter()PrintWriter를 받아서 HTML을 직접 출력한다.

PrintWriter writer = resp.getWriter(); writer.println("<h1>Hello Servlet</h1>");

HTTP 메서드 처리

service()에서 직접 분기

req.getMethod()로 HTTP 메서드를 문자열로 받아서 직접 분기할 수 있다.

protected void service(HttpServletRequest req, HttpServletResponse resp) { String method = req.getMethod(); if (method.equals("GET")) { doGet(req, resp); } else if (method.equals("POST")) { doPost(req, resp); } }

실제로 HttpServlet이 이 분기를 내부적으로 해주기 때문에, 보통은 doGet(), doPost()만 오버라이드하면 된다.


요청 파라미터 처리

단일 파라미터

String name = req.getParameter("name");

다중 파라미터 (체크박스 등)

String[] hobbies = req.getParameterValues("hobby");

헤더 읽기

String userAgent = req.getHeader("User-Agent");

한글 깨짐 방지

POST 요청에서 한글이 깨지면 아래 설정을 맨 먼저 해야 한다.

req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html; charset=UTF-8");

정리

  • 서블릿 인스턴스는 싱글톤이라 인스턴스 변수에 상태를 저장하면 안 된다
  • 생명주기 메서드(init, destroy)는 각 1회, service는 요청마다 실행된다
  • 파라미터는 getParameter / getParameterValues로 꺼내고, 한글이면 인코딩 설정을 먼저 한다