✏️ [Spring] Dispatcher Servlet

박상민·2024년 1월 3일
1

개념 정리!

목록 보기
6/18
post-thumbnail

스프링을 공부하면서 자주 보는 키워드가 있다. Servlet, Dispatcher Servlet 등이 그 예시이다.

이전에 Dispatcher Servlet에 대해서 작성한 글이 있지만 이번에는 더 자세히 알아보려고 한다.

⭐️ Servlet

Servlet은 동적인 웹페이지를 만들 때 사용되는 자바 기반 프로그래밍 기술이다. Servlet은 복잡한 웹 요청과 응답 과정을 간단한 메서드 호출로 다룰 수 있게 해준다.

public class ResponseJsonServlet extends HttpServlet {
    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {...}

📌 Servlet 동작 방식

클라이언트가 웹 서버에 HTTP 요청 메세지를 보내면 서버가 request, response 객체를 생성하고 서블릿 컨테이너에 있는 Servlet을 호출하면서 객체를 넘겨준다. Servlet이 작업을 한 뒤 종료되면서 HTTP 응답 메세지를 반환한다.

HTTP 응답에서 Content-Length 등의 부가 정보는 서버가 자동으로 생성한다.

⭐️ Dispatcher Servlet

Dispathcher Servlet의 Dispatch는 '보내다'라는 뜻을 가지고 있다. 그리고 이 단어를 포함한 디스패처 서블릿은 HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러(Front Controller)라고 정의할 수 있다.


디스패처 서블릿은 스프링 MVC의 중앙 서블릿이며 어플리케이션으로 오는 모든 요청을 핸들링하고 공통 작업을 처리해준다.

이러한 패턴을 프론트 컨트롤러(Front Controller) 패턴이라고 부른다.

참고: https://velog.io/@pp8817/Front-Controller-%ED%8C%A8%ED%84%B4

이것을 보다 자세히 설명하자면, 클라이언트로부터 어떠한 요청이 오면 Tomcat과 같은 서블릿 컨테이너가 요청을 받게 된다. 그리고 이 모든 요청을 프론트 컨트롤러인 디스패처 서블릿이 가장 먼제 받게 된다. 그러면 디스패처 서블릿은 공통적인 작업을 먼저 처리한 후에 해당 요청을 처리해야 하는 컨트롤러를 찾아서 작업을 위임한다.

📌 Dispatcher Servlet의 장점

Spring MVC는 DisPatcher Servlet이 등장함에 따라 web.xml의 역할을 상당히 축소시켰다. 과거에는 모든 서블릿을 URL 매핑을 위해 web.xml에 모두 등록해야 했지만,
dispatcher-servlet이 해당 어플리케이션으로 들어오는 모든 요청을 핸들링해주고 공통 작업을 처리하면서 상당히 편리하게 이용할 수 있게 됐다.
결론적으로 컨트롤러를 구현해두기만 하면 디스패처 서블릿이 알아서 적합한 컨트롤러로 위임을 해주는 구조가 됐다.

📌 정적 자원(Static Resources)의 처리

Dispatcher Servlet이 요청을 Controller로 넘겨주는 방식은 효율적으로 보인다. 하지만 Dispatcher Servlet이 모든 요청을 처리하다보니 이미지나 HTML/CSS/JavaScript 등과 같은 정적 파일에 대한 요청마저 모두 가로채는 까닭에 정적 자원(Static Resources)을 불러오지 못하는 상황도 발생하곤 했다. 이러한 문제를 해결하기 위해 개발자들은 2가지 방법을 고안했다.

  • 정적 자원 요청과 애플리케이션 요청을 분리
  • 애플리케이션 요청을 탐색하고 없으면 정적 자원 요청으로 처리

1. 정적 자원 요청과 애플리케이션 요청을 분리
이에 대한 해결책은 두가지가 있는데 첫번째는 클라이언트의 요청을 2가지로 분리하여 구분하는 것이다.

  • /apps 의 URL로 접근하면 Dispatcher Servlet이 담당한다.
  • /resources 의 URL로 접근하면 Dispatcher Servlet이 컨트롤할 수 없으므로 담당하지 않는다.

이러한 방식은 괜찮지만 상당히 코드가 지저분해지며, 모든 요청에 대해서 저런 URL을 붙여주어야 하므로 직관적인 설계가 될 수 없다. 그래서 이러한 방법의 한계를 느끼고 다음의 방법으로 처리를 하게 되었다.

2. 애플리케이션 요청을 탐색하고 없으면 정적 자원 요청으로 처리
두번째 방법은 Dispatcher Servlet이 요청을 처리할 컨트롤러를 먼저 찾고, 요청에 대한 컨트롤러를 찾을 수 없는 경우에, 2차적으로 설정된 자원(Resource) 경로를 탐색하여 자원을 탐색하는 것입니다. 이렇게 영역을 분리하면 효율적인 리소스 관리를 지원할 뿐 아니라 추후에 확장을 용이하게 해준다는 장점이 있습니다.

📌 동작 과정

앞서 설명한대로 디스패처 서블릿은 적합한 컨트롤러와 메소드를 찾아 요청을 위임해야 한다. Dispatcher Servlet의 처리 과정을 살펴보면 다음과 같다.

  1. 클라이언트의 요청을 디스패처 서블릿이 받음
  2. 요청 정보를 통해 요청을 위임할 컨트롤러를 찾음
  3. 요청 할 컨트롤러로 위임할 핸들러 어댑터를 찾아서 전달함
  4. 핸들러 어댑터가 컨트롤러로 요청을 위임함
  5. 비지니스 로직을 처리함
  6. 컨트롤러가 반환값을 반환함
  7. 핸들러 어댑터가 반환값을 처리함
  8. 서버의 응답을 클라이언트로 반환함

출처
https://mangkyu.tistory.com/18
https://velog.io/@betterfuture4/Spring-Dispatcher-Servlet-%EC%A0%95%EB%A6%AC#1-%EB%94%94%EC%8A%A4%ED%8C%A8%EC%B2%98-%EC%84%9C%EB%B8%94%EB%A6%BFdispatcher-servlet

profile
스프링 백엔드를 공부중인 대학생입니다!

0개의 댓글