진짜 개발자
본문 바로가기

Web/JSP,Servlet

Servlet  - SpringMVC을 사용하기 전 꼭 알아야 할 Servlet

728x90

Servlet 이해하기.

Servlet 이란?

간단히 말씀드려, 자바진영의 CGI 라고 볼 수 있습니다. 우선 CGI가 무엇인지부터 알아보아야 할것 같습니다.

1. CGI

CGI란, 동적으로, 웹페이지를 생성하는 Web Server의 프로그램을 실행하기 위한 Interface를 의미합니다. 조금 더 쉽게 알려드리겠습니다.

1.1 CGI란?

CGI가 없는 웹서버

1

CGI가 없는 웹 서버의 경우 사용자의 요청에 따라, 미리 작성된 html 사용자에게 전송이 됩니다. 어렸을때, 학교에서 보던, 반마다 있던 게시판을 떠올려보시면, 됩니다. 게시판의 내용을 누가 수정하지 않는 이상, 학생들은 항상 같은 내용의 게시판을 보게 됩니다.

CGI

2

CGI가 있는 경우, 웹서버는 사용자의 요청에 따라 동적으로 html을 작성하여 반환해줍니다. 예를들면 야구장의 전광판 같은 것을 생각해보면 됩니다. 전광판은 분명 게시판과 비슷한 역할을 하는데, 전광판을 조종하는 관리자의 설정에 따라 야구장의 관람객들은 다른 화면을 볼 수 있습니다.

1.2 다른 CGI와의 차이점

Servlet은 Java진영의 CGI라고 말씀드렸습니다. 그렇다면 다른 CGI와의 차이점은 무엇이고 왜 Servlet을 사용할까요?

여타 CGI (C, C++ …)

cgi

출처 - https://www.javatpoint.com/servlet-tutorial

위의 그림은 Serlvet이 아닌 다른 CGI 를 나타내는 그림입니다. 문제는, 사용자의 요청에 따라 별도의 Process를 생성한다는 점입니다. 때문에 사용자의 요청이 증가할수록 웹서버의 부하가 엄청나게 증가합니다.

Servlet

servlet

출처 - https://www.javatpoint.com/servlet-tutorial

Servlet은 Thread를 생성하여, CGI(Servlet)을 실행합니다. 때문에 아래와 같은 이점이 있습니다.

  • 스레드는 Stack, PC 만을 별도로 할당하고 다른 스레드들과, Heap, Data, Code 영역을 공유하기 때문에 자원이 절약되며, 서버에 부하가 덜 갑니다.
  • 운영체제의 특징상, 프로세스간 데이터를 주고 받는것은 어려워 별도의 장치가 필요한데, 스레드는 메모리 공유를 통해 데이터를 손쉽게 주고 받을 수 있습니다. (ServletContext)

2. Servlet

2.1 동작과정

  1. 사용자가 /hello 로 요청을 보낸다.
  2. ServletRequest, ServletResponse를 생성한다.
  3. web.xml에 기술된 servlet들중 /hello에 맵핑된 servlet에 요청을 맵핑한다.
  4. Servlet이 아직 생성된적이 없는 경우, 즉 처음 호출된 경우, Container는 web.xml을 참고하여, ServletConfig를 생성하여, Servlet의 init() 메소드의 매개변수로 전달하며 호출한다.
  5. Thread를 생성하고, 요청에 대응하는 Servlet의 public service() 메소드의 매개변수로 ServletRequest, ServletResponse를 전달하며 호출한다.
  6. public service() 메소드는, ServletRequest, ServletResponse를 각각 HttpServlertRequest, HttpServletResponse로 변환하며, protected service()의 매개변수로 전달하며 호출한다.
  7. request에 포함된 method의 type(get, post, put, delete …)에 따라서, doXXX() 메소드를 호출한다.

2.2 Servlet API

Servlet (interface)

public interface Servlet {
    public void init(ServletConfig config) throws ServletException;

    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;

    public String getServletInfo();

    public void destroy();
}
  • 모든 서블릿이 기본으로 구현해야하는 인터페이스입니다.

GenericServlet (abstract class)

  • protocol에 종속되지 않는 servlet입니다. 즉, Servlet은, http, websocket 등등에 사용될 수 있습니다.

  • Servlet, ServletConfig, Serializable 인터페이스를 구현한 추상클래스입니다

  • Http 프로토콜을 위해 GenericServlet을 상속받은 클래스가 바로 HttpServlet 입니다.

  • 이를 상속받는 Servlet은 service() 만을 별도로 구현하면 됩니다.

HttpServlet (class)

  • Http 프로토콜을 위한 Servlet으로 GenericServlet을 상속받습니다.
  • public service() 메소드는 ServletRequest, ServletResponse를 전달받아 HttpServletRequest, HttpServletResponse로 변환하고, protected service()를 호출합니다.
  • protected service()는 request의 method 타입에 따라서, doXXX() 메소드를 호출합니다.

ServletConfig (interface)

  • Container에 의해서, Servlet 별로 생성되는 객체로, web.xml로 부터 servlet의 정보를 가져올때 사용됩니다.
  • 이 객체덕분에 web.xml이 수정되는 경우 class를 수정할 필요가 없습니다.

ServletContext (interface)

  • 어플리케이션이 배포될때 Container에 의해서 생성되는 객체로, web.xml에서 설정 정보를 가져올때 사용됩니다.
  • 웹 어플리케이션 하나당 오직 한개의 ServletContext가 생성됩니다.
  • 모든 Servlet간의 어떤 정보가 공유되어야 할때 사용됩니다.
  • web.xml에 정보를 set 또는 get할때 사용할 수 있습니다.

3. Filter

filter

출처 - https://www.javatpoint.com/servlet-filter

  • Filter는 요청의 전, 후에 호출되어 별도의 처리를 추가할 수 있는 것입니다.

3.1 Filter의 사용처

예를들어 Filter가 사용되는 곳은 다음과 같습니다.

  • 모든 요청을 기록한다.
  • 요청에 담긴 내용을 변환한다.
  • 데이터를 압축한다.
  • 암호화 또는 비암호화한다.
  • 요청을 검증한다.

3.2 Filter API

Filter (interface)

  • 필터의 라이프사이클을 정의

  • init(FilterConfig)

    • web.xml을 기반으로 생성된 FilterConfig 객체를 이용하여, Filter를 초기화할때 한번만 호출됩니다.

    doFilter(HttpServlerRequest, HttpServletResponse, FilterChain)

    • Filter가 맵핑된 resource가 요청될때 호출되는 메소드, Filtering을 수행한다.

    destroy()

    • 서비스에서 제거될때 한번만 호출됩니다.

FilterChain (interface)

  • doFilter(ServlerRequest, ServletResponse)

    체인의 다음 Filter가 호출되도록 하거나, 체인의 마지막 Filter가 호출된경우, resource또는 Servlet이 호출됩니다.

FilterConfig

  • 웹 컨테이너에 의해서 생성되며, web.xml에 기술된 정보를 가져올때 사용됩니다.

4. RequestDispatcher와 sendRedirect

4.1 RequestDispatcher

_2020-07-05_12.13.17

  • 요청을 다른 자원의 요청(jsp, servlet, html)으로 보내거나, 요청에 다른 자원을 포함시킬때 사용됩니다.

  • 사용자에게 재요청을 하도록 하는게 아니기 때문에, url이 변경되거나, 다시 Filter를 타지 않습니다.

  • ServletRequest로 부터 RequestDispatcher 객체를 얻을 수 있습니다.

4.2 sendRedirect (HttpServletResponse)

  • HttpServletResponse의 메소드인 sendRedirect()는 응답으로 다른 Resource로 재요청하도록 할 수 있습니다.
  • 브라우저의 URL 표시줄을 이용하여 다른 요청을 하도록 하기 때문에 클라이언트 측에서 작동합니다.
  • Http Protocol은 무상태 프로토콜입니다. 때문에, 서버는 사용자의 매 요청들을 연관 짓지 못하고 새로운 요청으로 인식하게 됩니다. 이 때문에, 각 사용자의 상태를 유지하여 사용자들을 구분할 방법이 필요합니다.
  • URL Rewriting, Hidden Form Field, Cookies, HttpSession 등의 방법이 존재합니다.
  • 여러 사용자들의 요청을 구분하기 위해서 사용되는 사용자측에 저장되는 작은 정보 조각입니다.

동작

  1. Servlet의 Response에 Cookie를 포함시켜 전달합니다.
  2. 사용자측의 Browser의 캐시에 Cookie가 저장됩니다.
  3. 매 요청시 Cookie가 추가됩니다.
  1. Non-persistent

    • 하나의 session에서만 유효합니다. 즉, 브라우저가 종료될때 사라집니다.
  2. Persistent

    • 여러 세션에서 유효합니다. 브라우저가 종료될때 사라지지 않습니다. logout시 삭제됩니다.

5.2 HttpSession

  • Container는 각 사용자별로 session id 를 생성합니다. Container는 각 사용자를 구별하기 위해 이 session id 를 사용합니다.

동작

  1. 사용자가 요청을 하면, Web Container 는 고유한 session ID 를 생성합니다. 사용자에게 응답시 session ID 를 같이 전송합니다.
  2. 사용자는 각 요청에 session ID 를 포함시켜 전송합니다.

세부동작

  1. 새로운 요청이 생성되고 HttpServletRequest.getSession() 사용할때, 새로운 HttpSession이 생성됩니다.
  2. 응답에 이름이 JSESSIONID 이며 값이 Session Id 인, Cookie 를 추가합니다. (클라이언트 요청에 따라서, HttpSession 객체를 구분하기 위해 사용됩니다.)
  3. 요청시 JESSIONID 쿠키를 요청에 포함하여 전송합니다.
  4. JESSIONID의 값에 담긴 session Id를 이용해 session을 가져와 요청을 처리합니다.