ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 서블릿(Servlet)의 구조와 접근방식 (feat. CGI)
    Java 2021. 2. 16. 08:18
    반응형

    서블릿은 자바 소프트웨어 컴포넌트로 클라이언트의 요청을 처리하기 위해서 서버 안에서 실행됩니다 [1, 2]. 서블릿은 특정 클라이언트 프로토콜에 한정되지 않으나, 주로 HTTP를 많이 사용하기에 Servlet은 보통 HTTP Servlet을 의미하곤 합니다. 서블릿은 Sun Microsystems에 의해 CGI의 한계점을 극복하기 위해 개발되었습니다.

     

    서블릿은 javax.servlet 또는 javax.servlet.http 패키지에 존재하는 자바 인터페이스를 implement하여 만들어 집니다. 

     

    HTTP 서블릿은 주로 아래와 같은 목적을 위해 사용됩니다:

     

    • HTML 폼 형태로 제출된 데이터의 처리 및 저장
    • 동적 컨텐츠 제공 (예로, 클라이언트에 쿼리 요청에 해당되는 데이터를 데이터베이스에서 읽어서 전달)
    • Stateless한 HTTP를 대신해 State 정보를 관리

     
    이번 글에서는 아래와 같은 사항을 다룹니다:

    • 기본적인 서블릿의 구조
    • 서블릿 컨테이너
    • 서블릿 접근 방식

    기본적인 서블릿의 구조

    하나의 서블릿은 일반적으로 javax.servlet.Servlet 인터페이스를 implement한 클래스의 인스턴스입니다. 그러나 대부분의 경우에는 javax.servlet.GenericServlet 또는 javax.servlet.http.HttpServlet와 같은 스탠다드 구현체를 많이 사용합니다. 아래에서는 javax.servlet.http.HttpServlet 클래스를 extends하는 HTTP Servlet에 대해 다룹니다.

     

    서블릿을 시작하기 위해서, 서버 애플리케이션은 서블릿 클래스를 load하고 no-args 생성자를 호출하여 하나의 인스턴스를 생성합니다. 그리고, init(ServletConfig config) 메소드를 실행합니다. 클라이언트 요청을 처리하기 직전에 필요한 리소스나 처리는 모두 이 메소드에서 실행되며, 하나의 서블릿 인스턴스에 한 번 실행됩니다. 

     

    이 메소드는 ServletConfig 객체를 저장하여 추후에 서블릿의 getServletConfig() 메소드를 통해 retrieve할 수 있도록 합니다. 이 부분은 GenericServlet을 통해 처리되기에 GenericServlet을 extends한 클래스의 인스턴스는 super.init(config)을 init 메소드 시작 시에 실행하여 사용하게 됩니다.

     

    Servlet methods - Image from Author inspired by [2]

     

    각 서블릿은 다양한 클라이언트로부터 여러 요청을 처리합니다. Servlet 인터페이스는 service()라는 메소드를 정의하였는데, 이 메소드는 각 클라이언트 요청을 처리하며 클라이언트에 돌려줄 응답을 위한 컴퓨팅을 제어합니다. 요청이 전달하고 응답이 클라이언트에 돌아가면, 서블릿은 다음 요청을 위해 대기하게 됩니다. 

     

    HTTP 애플리케이션에서 service() 메소드는 어떤 형태의 HTTP 요청이 이뤄졌는지 확인(GET인지, POST인지 등)하고, 요청을 이러한 요청을 처리하도록 정의된 메소드로 포워딩합니다. 

     

    끝으로, destroy() 메소드를 실행하여 Servlet을 끝냅니다. 이 메소드는 init() 메소드 실행 시 얻은 리소스를 free하는 등의 처리를 위해 사용할 수 있습니다.

     

    서블릿 컨테이너

    서블릿의 라이프 사이클이 정해져 있다는 것은 벤더들이 서블릿을 위한 실행 환경인 서블릿 컨테이너를 구현할 수 있다는 것을 의미합니다. 구현하고자 하는 모든 사람은 서블릿 명세(specification)에 정의된 항목을 반드시 따라야 합니다. 그것을 통해 서블릿 명세를 따라 작성된 서블릿은 어떠한 서블릿 컨테이너에서도 실행될 수 있습니다.

     

    더욱이, 서블릿 컨테이너는 서블릿의 라이프 사이클 관리에 추가된 기능을 제공합니다 (initialization 파라미터 추가, 데이터베이스 연결 또는 다양한 리소스를 서블릿이 찾아 실행할 수 있도록 하는 것 등). 또한, 컨테이너는 서블릿을 위해 세션을 관리합니다. 

     

    HTTP는 stateless하기에, 컨테이너는 특정 클라이언트를 연결하는 특별한 토큰을 저장하는 임시 쿠키를 통해서 클라이언트의 identity를 보관합니다. 이 토큰은 바로 사용자 세션입니다. 이렇게 컨테이너가 다양한 요청들에서 서블릿에게 클라이언트를 식별해줌으로써, 클라이언트와 더욱 복잡한 인터랙션이 가능합니다. 만약 쿠키가 존재하지 않으면, 컨테이너는 클라이언트에 반환되는 HTML의 링크를 rewrite해서 우회하여 세션 정보를 관리할 수 있습니다.

     

    이것의 의미는 애플리케이션이 클라이언트 브라우저 안에 쿠키를 세팅하는 대신에, 컨테이너는 쿠키가 enabled되어 있는지 자동적으로 확인합니다. 만약 enabled되어 있다면 쿠키를 사용하고, 아니라면 대신 URL rewriting을 사용하여 세션을 관리합니다. 이후 애플리케이션 개발자는 유저 세션에 저장되어 있는 객체를 생성할 수 있고 이어지는 클라이언트 요청의 서블릿에서 사용할 수 있게 됩니다. 

     

    Security(인증/인가)는 security 프레임워크를 통해서 제공됩니다. 이것은 제한된 리소스와 인가된 사용자는 애플리케이션에 하드코딩 되지 않는 것을 의미합니다. 대신, 설정을 통해서 어떤 사용자가 어떤 리소스를 사용할 수 있는지 명시합니다. 그렇게 security 정책을 요구사항에 따라 쉽게 바꿀 수 있습니다.

     

     

    서블릿 접근 방식

    서블릿은 CGI와 같이 서버가 URLs을 프로그램 리소스에 연결합니다. 

     

    서블릿의 경우 이런 연결은 2가지 방식을 통해 이뤄질 수 있습니다. 애플리케이션 설정의 일부로 각 서블릿은 서블릿명으로 연결됩니다. 그 이름은 임의로 정해지나, 주로 서블릿이 제공하는 서블릿을 설명하는 내용을 포함합니다. 그 서블릿은 아래와 같은 URL을 통해 접근할 수 있습니다:

     

    www.server.com/servlet/ServletName

    위에서 ServletName은 설정 파일의 서블릿에 주어진 이름입니다. 이름 대신, 아래와 같이 정확한 서블릿명을 사용하여 접근할 수도 있습니다:

     

    www.server.com/servlet/com.wrox.db.ServletName

     

    서블릿은 또한 context path를 서블릿에 매핑하는 로지컬 매핑(logical mapping)을 통해서 접근할 수도 있습니다. 이것은 사용자에게 서블릿 액션의 의도에 대한 정보를 path를 통해 제공할 수 있기 때문에 서블릿명을 사용하는 것보다 의도를 잘 전달할 수 있습니다.

     

    컨테이너는 모든 요청을 가로채어 URL 안의 패턴을 확인하고 상응하는 서블릿을 요청을 넘깁니다. 

     

    비록 서블릿은 CGI를 개선한 형태지만, 서블릿 또한 여러 한계점을 가지고 있습니다. 그 중 가장 큰 점은 처리 로직과 관련된 점입니다. 

     

    첫 번째로는 코드 상에 텍스트 결과물을 아래와 같이 하드코딩하는 것은 애플리케이션 유지보수를 어렵게 만듭니다. 개발에도 복잡함을 더하는 동시에 HTML의 텍스트가 변경되었을 때에도 Java 코드가 다시 컴파일 되어야 합니다. 

     

    두 번째로, HTML 디자이너가 서블릿에서 오류를 내지 않으려면 어느 정도 Java를 이해하여야 합니다.

     

    이후 이러한 문제점을 개선하기 위해, JSP와 같은 프레임웍이 탄생하게 되었습니다.

     

     

     

     

    Reference

    [1] Jakarta Servlet

    [2] Servlet Essentials

    [3] Professional Apache Tomcat 5

    [4] Java Servlet Specification 4.0

     

    반응형
Kaden Sungbin Cho