서블릿 개발을 하면서 나는 항상 HttpServlet을 상속받고 @WebServlet 어노테이션을 붙이는 것이 당연하다고 생각해왔습니다. 그러나 최근 이 두 요소의 실제 역할과 관계에 대해 의문이 들어 공부해 보기로 했습니다.
먼저, Java Servlet 스펙을 살펴보겠습니다. 이 스펙에 따르면, 모든 서블릿은 javax.servlet.Servlet 인터페이스를 구현해야 합니다. 이 인터페이스는 다음과 같은 핵심 메소드를 정의합니다.
public interface Servlet {
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
public String getServletInfo();
public void destroy();
}
이 메소드들은 서블릿의 생명주기와 요청 처리를 담당합니다.
그렇다면 HttpServlet은 무엇일까요? HttpServlet은 Servlet 인터페이스를 구현한 GenericServlet의 하위 클래스입니다. HttpServlet은 HTTP 프로토콜에 특화된 추가 기능을 제공합니다. 특히, service 메소드를 오버라이드하여 HTTP 메소드(GET, POST 등)에 따라 적절한 do* 메소드를 호출합니다.
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
doGet(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
}
// ... 기타 HTTP 메소드들
}
이렇게 함으로써 개발자는 각 HTTP 메소드에 대한 처리를 쉽게 구현할 수 있습니다.
그렇다면 @WebServlet은? 놀랍게도 이 어노테이션은 서블릿의 기능과는 직접적인 관련이 없었습니다. Java EE 6에서 도입된 이 어노테이션은 서블릿의 선언적 등록을 위한 것입니다.
@WebServlet의 주요 속성들:
- name: 서블릿의 이름
- urlPatterns: 서블릿에 매핑될 URL 패턴
- loadOnStartup: 서블릿의 로드 순서
- initParams: 초기화 파라미터
- asyncSupported: 비동기 처리 지원 여부
예를 들어:
@WebServlet(name = "MyServlet", urlPatterns = {"/hello"}, loadOnStartup = 1)
public class MyServlet extends HttpServlet {
// 서블릿 로직
}
이 어노테이션은 사실상 web.xml의 <servlet> 및 <servlet-mapping> 요소를 대체합니다.
그렇다면 @WebServlet 없이는 서블릿을 등록할 수 없을까요? 그렇지 않습니다. 전통적인 web.xml을 사용하거나, Servlet 3.0부터 도입된 프로그래밍 방식의 서블릿 등록을 사용할 수 있습니다.
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext sc = sce.getServletContext();
ServletRegistration.Dynamic servlet = sc.addServlet("MyServlet", new MyServlet());
servlet.addMapping("/hello");
}
}
이 과정을 통해 저는 서블릿의 각 구성 요소가 각자의 역할을 가지고 있음을 깨달았습니다. Servlet 인터페이스는 기본 구조를, HttpServlet은 HTTP 특화 기능을, @WebServlet은 편리한 설정을 제공합니다.
나름의 결론을 내려보도록 하겠습니다. @WebServlet은 필수가 아닙니다. 하지만 xml이나 프로그래밍적으로 설정을 하는 것보다 많은 편리함을 제공해 주고 있습니다. 따라서 사용하는 것이 좋다고 생각합니다.
참고 자료:
- Java Servlet Specification 4.0: https://jcp.org/en/jsr/detail?id=369
- JavaDoc for HttpServlet: https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html
- Java EE 6 Tutorial: https://docs.oracle.com/javaee/6/tutorial/doc/
- Java Servlet API: https://docs.oracle.com/javaee/7/api/javax/servlet/package-summary.html