Servlet


웹 개발을 함에 있어 Http Servlet에 대한, 더 원론적으로 Servlet에 대한 이해가 많이 부족함을 느낀다.

‘자바 웹 개발 워크북’ 책을 구입을 한 것도 Spring boot를 학습하기 전에 기본적인 기반을 다져놓기 위함이다.


CGI 프로그램과 서블릿

웹 서버프로그램 사이의 데이터를 주고받는 규칙을 CGI(Common Gateway Interface) 라고 한다.

위와 같이 웹 서버에 의해 실행되며 CGI 규칙에 따라서 웹 서버와 데이터를 주고 받도록 작성된 프로그램이 CGI 프로그램이다.

서블릿

자바 CGI 프로그램은 컴파일 방식이다. 자바로 만든 CGI 프로그램이 바로 Servlet 이다. 서블릿이 다른 CGI 프로그램과 다른 점은 웹 서버와 직접 데이터를 주고받는 것이 아니라. 서블릿 컨테이너(톰캣)과 같은 전문 프로그램에 의해 관리된다는 점이다.

서블릿 컨테이너

서블릿의 생성과 실행, 소멸 등 생명주기를 관리하는 프로그램 이 바로 서블릿 컨테이너 이다. 서블릿 컨테이너가 서블릿을 대신하여 CGI 규칙에 따라 웹 서버와 데이터를 주고받는다. 따라서 서블릿 개발자는 CGI 규칙에 대해서는 알 필요가 없고 대신 서블릿 컨테이너와 서블릿 사이의 규칙을 알아야 한다. (서블릿 클래스는 서블릿 인터페이스를 구현해야 한다던가, init, service, destroy 등의 메소드를 오버라이딩 해야한다던가.)

위의 그림을 참고하자. 톰캣과 같은 WAS는 javaEE 기술 중 서블릿, JSP등 웹 관련 부분만 구현한 서블릿 컨테이너 이다.

#### 실습 실습은 이클립스에서 dynamic web으로 진행하였다. 따라서 프로젝트 디렉토리의 구조 역시 이클립스에서 정의한 구조로 진행된다.(intelliJ는 아직 덜 익숙)

어차피 이후 스프링 부트를 사용할 때의 디렉토리 구조도 달라지고 전반적으로 gradle과 같은 빌드 도구를 활용할 예정이기 때문에 큰 의미를 두지는 않겠다.

다만 web.xml 은 웹 어플리케이션 배치 설명서로써 서블릿, 필터, 리스너, 매개변수, 기본 웹 페이지 등 웹 어플리캐이션 컴포넌트들의 배치 정보 를 담아두는 파일임은 기억하자.

서블릿 컨테이너(톰캣 등)은 클라이언트의 요청을 처리할 때 web.xml과 같은 배치 설명서를 참고하여 서블릿 클래스를 찾거나 필터를 실해앟는 등의 작업을 수행한다.

사설이 길었다. 서블릿에 대한 실습을 하기 위해 코드를 먼저 살펴보자.

위에서 HelloWorld와 같이 서블릿 클래스는 반드시 Servlet interface 를 구현해야 한다.

서블릿 컨테이너가 서블릿에 대해 호출할 메서드를 정의한 것이 Servlet 인터페이스 이기 때문.

###### 서블릿 생명주기 메서드

  • init()
    • init()는 서블릿 컨테이너가 서블릿을 생성한 후 초기화 작업 을 수행하기 위해 호출하는, 생성자와 같이 단 한 번 호출되는 메서드 이다. 서블릿이 클라이언트의 요청을 처리하기 전에 준비할 작업 이 있다면 init() 메서드를 작성함으로써 진행한다. 이를테면 데이터베이스 연결, 외부 스토리지 서버와의 연결, 프로퍼티 로딩 등 클라이언트의 요청을 처리하는데 필요한 자원을 미리 준비할 수 있다.
  • service()
    • 클라이언트가 요청할 때 마다 호출되는 메서드 이다. 실질적으로 서비스 작업을 수행하는 메서드로써 바로 이 메서드에 서블릿, 즉 자바 프로그램이 해야 할 일을 작성한다.
  • destroy()
    • 서블릿 컨테이너가 종료되거나 웹 어플리케이션이 멈출 때, 또는 해당 서블릿을 비활성화 시킬 때 호출된다.

서블릿 구동 절차

  1. 클라이언트의 요청(HelloWorld)을 서블릿 컨테이너가 받는다.
  2. 해당 서블릿이 없다면 컨테이너는 메모리에 클래스를 로딩한다.
  3. 인스턴스를 생성한다.
  4. 생성자를 호출한다.
  5. init()을 호출한다.
  6. service()를 호출한다.
  7. service() 메서드에서 만든 결과를 HTTP 프로토콜에 맞추어 클라이언트에 응답한다.

WAIT!!

클라이언트의 요청으로부터 서블릿 컨테이너는 요청받은 서비스를 처리하기 위해 서블릿을 호출한다고 하였고 해당 서블릿이 메모리에 없다면 인스턴스 생성과 동시에 init()를 최초 한 번 호출한다고 하였다. 즉, 한 번 서블릿 인스턴스가 생성되면 웹 어플리케이션이 종료될 때 까지 메모리상에 유지된다는 의미이다. 이를 바탕으로 __인스턴스 변수에는 특정 사용자를 위한 데이터를 보관해서는 안된다는 점을 알 수 있다. 또한 클라이언트가 보낸 데이터를 일시적으로 보관하기 위해 서블릿의 인스턴스 변수를 사용해서도 안된다.__

###참고 및 출처

  • 자바 웹개발 워크북