[Spring] Spring MVC의 작동흐름 : DispatcherServlet과 FrontController

민지·2024년 1월 20일

Spring

목록 보기
5/6


서버에서는 웹 어플리케이션이 실행된다. 스프링부트를 통해 웹 어플리케이션을 제작하고, 스프링부트 안에는 Spring MVC가 있다.
이번 포스팅에서는 Spring MVC의 작동흐름을 살피고, DispatcherServlet과 FrontController의 개념을 살피는 것이 목적이다.

1. JAVA를 사용한 웹 어플리케이션의 발전

JAVA를 이용해 웹 어플리케이션을 만드는 방법이 어떻게 발전해왔는지 살펴보자.

1. Model 1 Arch - 뷰에 모든 코드 담기


자바로 웹 어플리케이션을 개발한 가장 초기에는, 뷰에 모든 코드를 담았다.
내가 스프링부트 프레임워크 도움없이 bbs게시판을 만들 때, jsp와 자바코드, 실제로 tomcat서버를 설치하는 과정, driver설치를 통해 db연동을 했을 때처럼, 모든 내용들은 jsp파일들로만 이루어졌다.

그 과정에서, 모든 코드흐름들, java코드, jsp코드, jsp와 db와의 소통 등 모든 코드를 jsp코드에 작성해야 했고, 스프링부트 프레임워크의 도움없이 모든 개발환경곽 코드를 개발자가 작성해야 했어서 매우 복잡했었다. 또한, 코드 주제별로 구분도 불가능했다 ..

이렇게 컨트롤러 없이 jsp로만 사용한 아키텍처Model 1 Arch이라 구분해보자.

2. Model 2 Arch - 주제에 따른 파일구조 구분

Model 1 Arch의 단점을 보완하기 위해, Model 2 Arch는 주제에 따른 파일구조를 구분했다.

  • 주제에 따른 파일구조 구분
    - Model : 뷰 <-> 컨트롤러 코드, HashMap 형태의 구조 (key - value)
    뷰에 model.put("name", value)을 통해 데이터를 넣고, 이후에 넣은 데이터를 다시 컨트롤러 코드로 가져오는 model.get("name")
    • View : 정보를 사용자에게 보여주는 역할 (jsp, html..)
    • Controller or Servlet : 전체 flow control

      즉, flow logic은 서블릿/컨트롤러 코드로 가서, 각 코드에 적힌 주요 기능을 수행한다. 그리고 사용자에게(브라우저 화면에) 어떻게 보여줄지 나타내는 뷰 로직은 뷰로, 컨트롤러 코드의 데이터를 뷰로 전달할 때의 모든 정보는 Model로 간다.
  • "Where to implement common features to all controllers?"
    그러나, 해당 모델2에서도 여전히 걱정거리가 있었는데, 모든 컨트롤러 코드에서 공통 기능을 구현하고 싶다면 어떻게 해야 할지에 대한 고민이었다.

예를 들어, 모든 서블릿에 공통으로 제공하는 기능으로 인증을 구현하고 싶다고 해보자. 그러면 어떻게 공통 기능을 구현할 수 있을까?

이것이 Front Controller 패턴으로의 발전을 이끌었다.

3. Model 2 Arch - Front Controller 추가

  • FrontController를 포함한 모델2의 구조
    브라우저에 오는 모든 request는 제일 먼저 단 하나의 컨트롤러(FrontController)로 간다. 그래서 보안과 같은 모든 공통기능을 FrontController layer에서 구현한다.
    보안인증과 같은 기능을 체크한 후, 적절한 컨트롤러/서블릿 혹은 뷰로 간다.

  • Front Controller 패턴
    - 모든 request가 가장 먼저 단 하나의 컨트롤러인 Front Controller로 흘러간다.

    • 그후, 프론트 컨트롤러는 컨트롤러(서블릿), 뷰, 모델로 가는 흐름을 제어한다.
    • 공통기능은 프론트 컨트롤러에 구현하면 된다.

지금까지, Dispathcer Servlet을 배우기 전, JAVA를 통한 웹 어플리케이션의 발전을 모델1 -> 모델2 -> frontController를 포함한 모델2의 흐름을 통해 살펴보았다.

2. Spring MVC Front Controller - Dispatcher Servlet

제목 그대로 Dispatcher Servlet이란, Spring MVC의 Front Controller이다.
그럼 Dispatcher Servlet의 작동구조를 살펴보자!

Dispatcher Servlet의 작동구조

  • Dispatcher Servlet은 프론트 컨트롤러 역할을 한다.

A : Receives ALL HTTP request

모든 request는 Dispatcher Servlet으로 가게 된다. 로그인 url로 가든, say-hello url이든 say-hello-jsp url을 입력하든.. 모든 http request는 우선 바로 Dispathcher Servlet으로 가게 된다.

B : Processes HTTP request

B1 : 올바른 Controller method 찾기 - Based on request URL

@Controller
public class LoginController {
   @RequestMapping("/login")
   public String login(@RequestParam String name, ModelMap model) {
     	model.put("name", name);
      	return "login";
  	}
}

모든 url(/login, /logout, /say-hello..)이 들어왔다면, 어떤 url인지 식별해서 올바른 컨트롤러 코드를 찾아주어야 한다.

위의 예시처럼, /login url에 대한 http request라면, 해당 url에 해당하는 @RequestMapping을 찾아, 올바른 컨트롤러(LoginController)를 찾는다.

B2 : Controller method 실행하기 - Returns Model and View name

찾은 컨트롤러 메서드를 실행한다. 실행결과, 컨트롤러 메서드는 보통 모델과 뷰 이름을 리턴한다.

즉, 위 예제에서는 model에 "name"속성명을 추가하고, 뷰 이름인 "login"을 리턴한다.

B3 : 올바른 View 찾기 - Using ViewResolver

컨트롤러에서 리턴한 login 뷰 이름에 맞는, 렌더링할 적절한 뷰를 찾아야 한다.

위 예시의 경우, login.jsp 뷰를 찾아야 한다. Dispatcher Servlet이 login을 login.jsp로 매핑하는 바법은, 앞선 포스팅에서 application.properties에서 설정한 prefix, suffix를 참고해, 그 결과 특정 폴더 안에 있는 login.jsp를 찾게 된다.

이러한 로직은 ViewResolver에서 실행된다. 즉, ViewResolver는 login을 특정한 jsp파일에 mapping시킨다,

다시 말해, Dispathcer Servlet은 viewResolver와 대화하고 정확한 view이름을 받는다.

B4 : 뷰 렌더링하기

C : Returns HTTP Response

마치며 .. - Dispatcher Servlet flow

위 Spring MVC의 Front Controller인 Dispatcher Servlet의 작동구조를 간단하게 정리해보겠다.

  1. Receives HTTP Request

    → localhost:8080/login

  2. Processes HTTP Request

    1. Identifies correct Controller method

      Based on request URL

      → /login → login()

    2. Executes Controller method

      Returns Model and View Name

      → Puts 1 datas into model

      → Return view name ⇒ login

    3. Identifies correct View

      Using ViewResolver

      → /WEB_INT/jsp/login.jsp

    4. Executes view

  3. Returns HTTP Response

profile
배운 내용을 바로바로 기록하자!

0개의 댓글