Servlet을 고민해보자

허진혁·2022년 11월 23일
0

고민해보자

목록 보기
6/12
post-thumbnail

스프링을 처음 접해보았을 때 들었던 것들 ApplicationContext, springboot, spring security 등등이 있었지만 가장 일찍 접했던 것은 MVC패턴이었다.

접하자마자 보았던 문장 "dispatcherServlet이 프론트 컨트롤러 이다."
아직도 이 때의 순간이 잊혀지지 않는다. 처음 접하던 스프링이라 그런지 문장에서 알아 들었던 것은 동사와 조사뿐이었다.

그래서 MVC패턴은 다음시간에 고민하고 웹과 서버를 연결하는 서블릿부터 고민해보기로 합니다 !!!!!!!! Let's go

WAS(Web Application Server)

예전에 웹은 정적 자원 만을 반환했지만, 점점 기능들이 발전하면서 수요에 따른 동적 웹도 중요해지고 있다. 그래서 필요한 WAS!!
DB에 접근하고 다양한 로직을 처리하여 동적 자원을 만들 수 있기 때문이다.

자바에서 WAS는 (고양이) 톰캣이 서블린 컨테이너 역할을 한다.
이제 점점 낯선 단어들의 향연이 나타나고 있다. 그래도 어쩌겠나..
(알아야 생각하고, 고민하고, 코딩하지)

서블릿

우선 위키피디아의 정의를 보면

자바 서블릿(Java Servlet)은 자바를 사용하여 웹페이지를 동적으로 생성하는 서버측 프로그램 혹은 그 사양을 말하며, 흔히 "서블릿"이라 불린다. 자바 서블릿은 웹 서버의 성능을 향상하기 위해 사용되는 자바 클래스의 일종이다.

서블릿은 "웹과 요청, 응답을 할 때, 동적 처리가 가능한 자바 프로그램"인 것이다.

자바에서 정의된 서블릿을 보며 생각을 해보자.

package javax.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 void destroy();
}

init()으로 생성을 한 후, service()에서 비지니스 로직이 실행되고, destroy()로 삭제가 되는 구성이구나 !!

다음으로 Servlet이 인터페이스 이니 Servlet의 기능을 구현한 GenericServlet을 상속받은 HttpServlet을 찾을 수 있었다.

package javax.servlet.http;

/**
Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doMethod methods listed above).
Likewise, there's almost no reason to override the doOptions and doTrace methods.
Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections. See the Java Tutorial on Multithreaded Programming  for more information on handling multiple threads in a Java program.
*/
public abstract class HttpServlet extends GenericServlet {
    
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String msg = lStrings.getString("http.method_get_not_supported");
        sendMethodNotAllowed(req, resp, msg);
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String msg = lStrings.getString("http.method_post_not_supported");
        sendMethodNotAllowed(req, resp, msg);
    }

    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String msg = lStrings.getString("http.method_put_not_supported");
        sendMethodNotAllowed(req, resp, msg);
    }
    
    protected void doDelete(HttpServletRequest req,
                            HttpServletResponse resp)
        throws ServletException, IOException {

        String msg = lStrings.getString("http.method_delete_not_supported");
        sendMethodNotAllowed(req, resp, msg);
    }
}

주석에 정말 자세하게 설명되어 있었다. 자바와 스프링을 공부할 때 이렇게 찾아들어가면서 주석으로 인한 설명이 정말 깔끔하다.

"abstract class to be subclassed to create an HTTP servlet suitable for a Web site"

HttpServlet은 웹 사이트에 적합한 서블릿을 만드는 추상클래스이다.
그리고 HttpServlet을 상속받으면 다음과 같은 메서드 중 필요한 것들을 오버라이드 해야한다.

  • doGet() : HTTP GET 요청에 대한 처리
  • doPost() : HTTP POST 요청에 대한 처리
  • doPut() : HTTP PUT 요청에 대한 처리
  • doDelete() : HTTP DELETE 요청에 대한 처리
  • init() : 서블릿 생성
  • destroy() : 서블릿 파괴

여기서 신기한 것을 찾았다(야호~). init()과 destroy()는 있는데 service()만 없네..?

There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doMethod methods listed above).

HttpServlet의 service() 메서드가 HTTP 요청을 보고, doMethod() 같은 메서드로 실행해주기에 오버라이딩 해줄 필요가 없는 것이다.

서블릿 컨테이너

자 이제 서블릿은 한 문장으로 정리한다면 "동적 처리가 가능한 웹"으로 할 수 있게 되었다. 그럼 이러한 서블릿을 관리하는 것이 서블릿 컨테이너 라는 느낌은 들었다. (앞서 말한 톰캣이 서블릿 컨테이너!)

그렇다면 관리한다는 것은 무엇을 해준다는 것일까??

서블릿 컨테이너가 하는 일
1. 웹 서버와 통신하기
2. 서블릿 생명주기 관리
3. 멀티쓰레드 지원 및 관리
4. 선언적인 보안 관리

서블릿 동작방식

지금까지 정적 웹에서 동적웹으로 바뀌면서 필요한 WAS부터 서블릿, 서블릿 컨테이너에 대해 배웠다.

이제 고민해야 할 것은 '_서블릿 컨테이너는 어떻게 클라이언트의 요청에 대응하는 서블릿을 찾아 service()메서드를 실행시켜 필요한 로직을 실행하는가?' 이다.

1. 웹 서버가 WAS에게 클라이언트가 보낸 요청을 건네줌

1-1. HTTP request의 정보를 통해 HttpServletRequest 객체 생성

1-2. 클라이언트에게 보낼 응답을 위해 HttpServletResponse 객체 생성

1-3. 서블릿 컨테이너의 web.xml 설정에서 요청 url에 대응되는 서블릿을 선택

1-4. 선택된 서블릿에 HttpServletRequest와 HttpServletResponse를 넘겨줌

2. 서블릿 컨테이너가 선택된 서블릿 객체를 메모리에 올림

2-1. 서블릿 컨테이너가 선택된 서블릿 객체를 컴파일

2-2. 서블릿 객체를 만들어 메모리에 올림

2-3. 메모리에 올라가면서 서블릿의 init() 메서드 실행

3. 서블릿 컨테이너가 해당 서블릿 객체의 service() 메서드를 호출함

3-1. 하나의 쓰레드에서 요청에 대응되는 서블릿의 service() 메서드를 호출함

3-2. service() 메서드 내부에서 HttpServletResponse에 필요한 내용을 담아서 반환함

참고
https://www.youtube.com/watch?v=Zimhvf2B7Es
https://github.com/joelonsw/woowacourse-TIL/blob/master/Level2/2021-06-19.md
https://tecoble.techcourse.co.kr/post/2021-05-23-servlet-servletcontainer/
https://yongho1037.tistory.com/692

profile
Don't ever say it's over if I'm breathing

0개의 댓글