개발/Spring
[Spring] Spring MVC 요청의 흐름
함수형 인간
2025. 3. 14. 06:07
Spring MVC는 Model, View, Controller 패턴을 기반으로 하는 웹 프레임워크로, 사용자 요청 처리부터 응답 생성까지 일련의 흐름을 가지고 있다. 기본적인 흐름은 다음과 같다.
1. DispatcherServlet (Front Controller) 요청 수신:
- 클라이언트의 모든 요청은 DispatcherServlet (Front Controller)이 가장 먼저 받는다.
- DispatcherServlet은 web.xml (또는 Java Config)에 설정되어 있으며, 특정 URL 패턴 (예: /)에 매핑된다.
2. HandlerMapping에 요청 위임:
- DispatcherServlet은 HandlerMapping에게 요청을 처리할 적절한 Controller를 찾아달라고 요청.
- HandlerMapping은 URL, HTTP 메서드(GET, POST 등) 등을 기반으로 요청을 처리할 Controller를 결정.
- @RequestMapping, @GetMapping, @PostMapping 등의 어노테이션을 사용하여 Controller와 URL을 매핑.
3. Controller에서 요청 처리:
- HandlerMapping이 찾은 Controller는 비즈니스 로직을 처리.
- Controller는 Service 객체를 호출하여 실제 작업을 수행. (Service 객체는 데이터베이스 액세스, 비즈니스 로직 등을 담당)
- Controller는 처리 결과를 Model 객체에 담아 DispatcherServlet에게 반환. Model은 View에 전달될 데이터를 저장.
- Controller는 어떤 View를 사용할지도 결정하여 View 이름을 함께 반환. (또는 @ResponseBody를 사용하여 직접 응답 데이터를 생성할 수 있다.)
4. ViewResolver를 통해 View 선택:
- DispatcherServlet은 Controller가 반환한 View 이름을 기반으로 ViewResolver에게 실제 View 객체를 찾아달라고 요청.
- ViewResolver는 설정에 따라 JSP, Thymeleaf, FreeMarker 등 적절한 View 템플릿을 찾아 View 객체를 생성. (예: /WEB-INF/views/ 폴더 아래의 JSP 파일)
5. View에서 응답 생성:
- DispatcherServlet은 View 객체에게 Model 데이터를 전달.
- View는 Model 데이터를 사용하여 동적인 HTML, JSON, XML 등의 응답을 생성.
- JSP의 경우, JSTL, EL 표현식 등을 사용하여 Model 데이터에 접근.
6. DispatcherServlet이 클라이언트에게 응답 전송:
- View가 생성한 응답(HTML, JSON 등)을 DispatcherServlet이 클라이언트에게 전송.
7. 예시
- Client -> DispatcherServlet: /hello?name=World (GET 요청)
- DispatcherServlet -> HandlerMapping: /hello 요청을 처리할 Controller 찾아줘!
- HandlerMapping -> DispatcherServlet: MyController의 sayHello 메서드가 처리해야 해! (HandlerMethod 객체 반환)
- DispatcherServlet -> RequestMappingHandlerAdapter: MyController.sayHello 메서드 실행해줘! (그리고 요청 정보도 함께 전달)
- RequestMappingHandlerAdapter:
- sayHello 메서드의 @RequestParam("name")을 보고, 요청 파라미터 name의 값("World")을 가져와서 name 변수에 바인딩.
- Model 객체를 생성하여 sayHello 메서드의 model 파라미터에 전달.
- sayHello 메서드 호출.
- sayHello 메서드가 반환한 "helloView" 문자열(View 이름)을 DispatcherServlet에게 반환.
- DispatcherServlet -> ViewResolver: "helloView"라는 이름의 View를 찾아줘!
- ViewResolver -> DispatcherServlet: helloView에 해당하는 View 객체(JSP 등) 반환
- DispatcherServlet -> View: Model 데이터를 줄 테니 응답(HTML)을 만들어줘!
- View: Model 데이터를 사용하여 HTML 생성.
- DispatcherServlet -> Client: 생성된 HTML 응답 전송.
핵심 컴포넌트:
- DispatcherServlet: Front Controller. 모든 요청을 받고, 다른 컴포넌트에게 작업을 분배.
- HandlerMapping: 요청 URL과 Controller를 매핑.
- Controller: 실제 요청 처리 (비즈니스 로직 호출, Model 생성, View 이름 반환).
- Service: 비즈니스 로직을 담당하는 컴포넌트 (Controller에서 호출됨).
- Model: View에 전달할 데이터를 담는 객체.
- ViewResolver: View 이름을 실제 View 객체로 변환.
- View: Model 데이터를 사용하여 응답(HTML, JSON 등)을 생성.
추가 설명:
- Interceptor: DispatcherServlet과 Controller 사이에서 요청/응답을 가로채서 추가적인 작업을 수행할 수 있다 (로깅, 인증/인가 등). HandlerInterceptor 인터페이스를 구현하여 사용.
- @RestController: @Controller + @ResponseBody 를 합친 어노테이션. RESTful API를 만들 때 주로 사용되며, 메서드의 반환 값이 HTTP 응답 본문으로 직접 전송. (View를 거치지 않음)
- Data Binding/Validation: 클라이언트에서 전송된 데이터를 Java 객체(Form 객체, DTO)에 자동으로 바인딩하고, 유효성 검사를 수행하는 기능이 있다. (@Valid, BindingResult 등)
- Exception Handling: 애플리케이션에서 발생할 수 있는 예외를 처리하는 방법을 제공. (@ControllerAdvice, @ExceptionHandler 등)