1. 서블릿(Servlet)이란?
서블릿은 서버 쪽에서 실행되면서 클라이언트의 요청에 따라 동적으로 서비스를 제공하는 자바 클래스이 다. 서블릿은 자바로 작성되어 있으므로 자바의 일반적인 특징을 모두 가진다. 하지만 서블릿은 일반 자바 프로그램과 다르게 독자적으로 실행되지 못하고 톰캣과 같은 JSP/Servlet 컨테이너에서 실행된다는 차이가 있다. 서블릿은 서버에서 실행되다가 웹 브라우저에서 요청을 하면 해당 기능을 수행한 후 웹 브라우저에 결과를 전송한다. 서버에서 실행되므로 보안과 관련된 기능도 휠씬 안전하게 수행할 수 있다.
클라이언트가 웹 서버에 요청하면, 웹 서버는 그 요청을 톰캣과 같은 웹 애플리케이션 서버(WAS)에 위임한다. 그러면 WAS(톰캣)는 각 요청에 해당하는 서블릿을 실행한다. 그리고 서블릿은 요청에 대한 기능을 수행한 후 결과를 반환하여 클라이언트에 전송한다(톰캣 서버 경로 설정). 서블릿은 단순히 고정된 정보를 브라우저에 보여주는 용도는 웹 서버로도 충분하다. 그러나 쇼핑몰 화면에 실시간으로 변하는 상품의 할인 가격을 보여주려면 상품의 할인 가격을 데이터베이스에서 가져오는 기능이나 직접 계산하는 기능이 필요하다. 따라서 그런 기능을 서버 쪽에서 서블릿이 처리해 주면 상품 할인 가격 표시처럼 웹 페이지에서 동적으로 변하는 정보를 효과적으로 다룰 수 있다. 그 외 서블릿은 다음과 같은 특징이 있다.
- 서버 쪽에서 실행되면서 기능을 수행한다.
- 기존의 정적인 웹 프로그램의 문제점을 보완하여 동적인 여러 가지 기능을 제공한다.
- 스레드 방식으로 실행된다.
- 자바로 만들어져 자바의 특징(객체 지향)을 가진다.
- 컨테이너 종류에 상관없이 실행된다(플랫폼 독립적).
- 보안 기능을 적용하기 쉽다.
- 웹 브라우저에서 요청 시 기능을 수행한다.
2. 서블릿 API 계층 구조와 기능
서블릿은 자바로 만들어졌으므로 당연히 클래스들 간의 계층 구조를 가진다
서블릿 API는 Servlet과 ServletConfig 인터페이스를 구현해 제공하며 GenericServlet 추상 클래스가 이 두 인터페이스의 추상 메서드를 구현한다. 그리고 이 GenericServlet을 다시 HttpServlet이 상속받는다.
1) 서블릿 API 구성 요소 특징
서블릿 구성 요소 | 기능 |
Servlet 인터페이스 | • javax.servlet 패키지에 선언되어 있다. • Servlet 관련 추상 메서드를 선언한다. • init(), service(), destroy(), getServletInfo(), getServletConfig()를 선언한다. |
ServletConfig 인터페이스 | • javax.servlet 패키지에 선언되어 있다. • Servlet 기능 관련 추상 메서드가 선언되어 있다. • getInitParameter(), getInitParameterNames(), getServletContext(), getServletName()이 선언되어 있다. |
GenericServlet 클래스 | • javax.servlet 패키지에 선언되어 있다. • 상위 두 인터페이스를 구현하여 일반적인 서블릿 기능을 구현한 클래스이다. • GenericServlet을 상속받아 구현한 사용자 서블릿은 사용되는 프로토콜 에 따라 각각 service()를 오버라이딩해서 구현한다. |
HttpServlet 클래스 | • javax.servlet.http 패키지에 선언되어 있다. • GenericServlet을 상속받아 http 프로토콜을 사용하는 웹 브라우저에서 서블릿 기능을 수행한다. • 웹 브라우저 기반 서비스를 제공하는 서블릿을 만들 때 상속받아 사용 한다. • 요청 시 service()가 호출되면서 요청 방식에 따라 doGet()이나 doPost() 가 차례대로 호출된다. |
GenericServlet은 일반적인 여러 통신 프로토콜에 대한 클라이언트/서버 프로그램에서 서블릿 기능을 구현하는 클래스이다. HttpServlet은 이 GenericServlet을 상속받는다. HttpServlet은 이름에서 알 수 있듯이 HTTP 프로토콜을 사용하는 서블릿 기능을 구현하는 클래스이다. 바로 이 HttpServlet을 상속받아 HTTP 프로토콜로 동작하는 웹 브라우저의 요청을 처리하는 서블릿이 만들어 사용할 서블릿이다. 그 외 다른 서 블릿 구성 요소들의 기능은 API 문서를 참고하기 바란다.
2) HttpServlet의 주요 메서드
메서드 | 기능 |
protected doDelete(HttpServletRequest req, HttpServletResponse resp) | 서블릿이 DELETE request를 수행하기 위해 service()를 통해서 호출된다. |
protected doGet(HttpServletRequest req, HttpServletResponse resp) | 서블릿이 GET request를 수행하기 위해 service()를 통해서 호출된다. |
protected doHead(HttpServletRequest req, HttpServletResponse resp) | 서블릿이 HEAD request를 수행하기 위해 service() 를 통해서 호출된다. |
protected doPost(HttpServletRequest req, HttpServletResponse resp) | 서블릿이 POST request를 수행하기 위해 service() 를 통해서 호출된다. |
protected service (SerlvetRequest req, ServletResponse resp) | request를 public service()에서 전달받아 doXXX() 메서드를 호출된다. |
public service (SerlvetRequest req, ServletResponse resp) | 클라이언트의 request를 protected service()에게 전달한다. |
클라이언트 요청 시 public service() 메서드를 먼저 호출한 후 다시 protected service() 메서드를 호출한다. 그런 다음 다시 request 종류에 따라 doXXX() 메서드를 호출하는 과정으로 실행된다.
3. 서블릿의 생명주기 메서드
서블릿도 자바 클래스이므로 실행하면 당연히 초기화 과정 그리고 메모리에 인스턴스를 생성하여 서비스를 수행한 후 다시 소멸하는 과정을 거친다. 이런 단계를 거칠 때마다 서블릿 클래스의 메서드가 호출되 어 초기화, 데이터베이스 연동, 마무리 작업을 수행한다. 각 과정에서 호출되어 기능을 수행하는 메서드들 이 서블릿 생명주기 메서드이다. 따라서 서블릿 생명주기(LifeCycle) 메서드란 서블릿 실행 단계마다 호출되어 기능을 수행하는 콜백 메서드를 말한다.
생명주기 단계 | 호출 메서드 | 특징 |
초기화 | init() | 서블릿 요청 시 맨 처음 한 번만 호출된다. 서블릿 생성 시 초기화 작업을 주로 수행한다. |
작업 수행 | doGet() doPost() |
서블릿 요청 시 매번 호출된다. 실제로 클라이언트가 요청하는 작업을 수행한다. |
종료 | destroy() | 서블릿이 기능을 수행하고 메모리에서 소멸될 때 호출된다. |
4. 서블릿 동작 과정
클라이언트 1이 요청하면 톰캣은 FirstServlet이 메모리에 로드되어 있는지 확인한다. 최초의 요청이므로 init() 메서드를 호출하여 FirstServlet 인스턴스를 메모리에 로드한다. 그런 다음 doGet()이나 doPost() 메서드를 호출하여 서비스를 한다.
클라이언트 2가 다시 동일한 서블릿을 요청하면 톰캣은 다시 FirstServlet이 메모리에 로드되어 있는지 확인한다. 이번에는 메모리에 있는 것이 확인되므로 바로 doGet()이나 doPost() 메서드를 호출하여 서비스를 한다.
톰캣을 실행한 후 브라우저로 요청하여 출력 결과를 확인해 본다. 맨 처음 브라우저에서 /hello로 요청하면 최초의 요청이므로 FirstServlet 클래스의 init()를 호출해 초기화한 후 메모리에 로드되어 doGet() 메서드를 호출하여 서비스를 한다.
그러나 다른 브라우저에서 동일한 서블릿 매핑 이름인 /hello로 요청하면 미리 메모리에 로드된 FirstServlet 클래스 서블릿이 재사용되므로 init()는 호출하지 않고 doGet() 메서드만 호출하여 서비스를 한다. 서블릿이 스레드 방식으로 동작하는 원리를 이해한다. 이처럼 동일한 작업의 경우 서블릿은 메모리에 존재하는 서블릿을 재사용함으로써 휠씬 빠르고 효율적으로 동작한다.