Spring/Spring MVC

[Spring] Servlet 서블릿

TheWing 2020. 11. 6. 18:32

Servlet

  • HTTP 통신 기반의 클래스를 살펴보면 어노테이션 기반, 매개변수나 서블릿 클래스가 활용된다
  • 자바 엔터프라이즈 에디션은 웹 애플리케이션 개발용 스펙과 API를 제공한다.
  • Request 당 Thread를 사용하게 된다.
  • 가장 중요한 클래스 중 하나가 HttpServlet이다.
  • Servlet은 웹 프로그래밍에서 클라이언트 요청을 처리하고 처리 결과를 클라이언트에 전송하는 기술이다.

CGI(Common gateway Interface)

  • 자바로 구현된 서블릿 등장 전에 사용하던 기술이다.
  • 별도로 제작된 웹 서버와 프로그램간의 교환 방식으로 어떠한 프로그래밍 언어로도 구현이 가능하고 , 별도로 만들어 놓은 프로그램에 HTML의 GET, POST방법으로 클라이언트 데이터를 환경변수로 전달하고 프로그램의 표준 출력 결과를 클라이언트에 전송하는것을 말한다

Servlet 특징

  • 클라이언트의 요청에 대해 동적으로 작동하는 웹 애플리케이션 컴포넌트이다.
  • HTML을 통해서 요청에 응답한다.
  • Java thread를 통해 동작 ( Request 당 하나의 thread를 사용)
  • MVC 패턴 중 Controller이다
  • HTTP Protocol Service를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받는다.
  • UDP보다 속도가 느리다
  • HTML 변경시 Servlet을 재컴파일 해야한다

Servlet 장점 (CGI와 비교)

  • 빠르다
  • OS 플랫폼에 독립적이다
  • 보안
  • 이식성

Servlet Container

  • 서블릿 컨테이너는 서블릿을 관리해주는 컨테이너라고 한다.
    • 톰캣, 제티, 언더토
  • 서블릿 컨테이너는 클라이언트의 요청을 받아주고 응답할 수 있도록 웹 서버와 소켓을 만들어서 통신한다.
  • Session 을 관리해주고
  • 네트워크 서비스
  • MIME 기반 메시지 인코딩 디코딩
  • 서블릿 생명주기 관리

Servlet Container 역할

  • 웹 서버와의 통신을 지원
    • 서블릿 컨테이너는 서블릿과 웹 서버가 쉽게 통신할 수 있게 도와준다. 소켓 기능들을 API로 제공하여 복잡한 과정을 생략하고, 개발자는 구현해야 할 비즈니스 로직에 대해서만 초점을 맞추면 된다.
  • Servlet LifeCycle 관리
    • 서블릿 컨테이너는 생명주기를 관리한다. 서블릿 클래스를 로딩하여 인스턴스화, 초기 메소드 호출, 요청을 받으면 적절한 서블릿 메소드를 호출한다
  • 멀티 쓰레드 지원 및 관리
    • 서블릿 컨테이너는 요청이 들어올 때 마다 새로운 thread를 생성하게된다, HTTP 서비스 메소드를 실행하고 thread는 죽게된다. 이러한 관리를 컨테이너가 관리해준다
  • 선언적인 보안 관리
    • 보안 관리는 XML 배포 서술자에 기록하므로 보안적 문제로 인해 자바 소스를 수정할 일이 없게 된다.

Servlet 동작 방식

서블릿 생명주기(Servlet Life Cycle)

  • 서블릿 컨테이너가 서블릿 인스턴스의 init() 메소드를 호출하여 초기화 한다
    • 최초 요청을 받았을 때 한번 초기화 하고 나면 그 다음 요청부터는 이 과정을 생략한다
  • 서블릿이 초기화 된 다음부터 클라이언트의 요청을 처리할 수 있다. 각 요청은 별도의 쓰레드로 처리하고 이때 서블릿 인스턴스의 service() 메소드를 호출한다.
    • 이 안에서 HTTP 요청을 받고 클라이언트로 보낼 HTTP 응답을 만든다
    • service() 는 보통 HTTP Method에 따라 doGet() , doPost() 등으로 처리를 위임한다.
    • 따라서 보통 doGet() 또는 doPost() 를 구현한다.
  • 서블릿 컨테이너는 판단에 따라서 해당 서블릿을 메모리에서 내려야 할 시점에 destroy()를 호출한다

프로젝트 생성

  • 아래와 같이 webapp으로 생성해준다

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope> 
</dependency>
  •  provided
    • 런타임시에는 동작하지만 war로 패키징시에는 포함되어있지 않는다
  • Project structure 설정

  • java 폴더 생성후 source지정해줌

  • web.xml 아래코드추가
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>HelloServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>
  • 예제
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        resp.getWriter().write("Hello Servlet");
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("init");
    }
}
  • HelloServlet클래스를 HttpServlet을 상속받아 생성 후 Run 시켜준다

  • /hello 입력시

  • servletdemo_war_exploded URL 을 입력해줘야해서 번거로움이 있기 때문에 URL을 재지정해준다

  • Application context란에 "/" 입력 후 적용시키고 다시 Run 시키면
  • http://localhost:8080/hello 로 URL 입력을 했을때 아래와 같이 결과가 나온다

  • 톰캣 종료시

  • 가장 먼저 init() 메소드를 호출후 Get 요청을 받아 doGet() 메소드를 호출한다 톰캣 서버 종료시 destroy() 메소드가 호출이된다

결론

  • 클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술이다

Reference