Spring/강의

[📕 기초 Spring] 3-3. Spring MVC

가지코딩 2025. 5. 3. 17:53

📕 목차

  1. Spring MVC
  2. Spring MVC 구조
  3. Spring MVC 흐름
  4. 핵심 구성 요소 정리 
  5. Spring MVC 패턴의 장점

1. Spring MVC

  • 자바 기반의 웹 애플리케이션을 개발하기 위한 프레임워크인 Spring Framework의 일부이다.
  • MVC 패턴에 프론트 컨트롤러 패턴, 어댑터 패턴이 적용된 구조를 가지고 있다.
  • 이 패턴은 코드의 가독성과 유지보수성을 높이고, 요청 처리 과정을 역할에 따라 분리하여 효율적인 개발을 돕는다.

2. Spring MVC 구조

 

Spring MVC에서 프론트 컨트롤러의 역할

  • DispatcherServlet: 모든 HTTP 요청은 처음에 DispatcherServlet을 통해 들어온다. 이 서블릿은 요청을 처리할 수 있는 적절한 핸들러를 찾고, 그 핸들러가 처리할 수 있는 방법을 결정한다.
    • 요청 분배: 요청 URL을 바탕으로 어떤 컨트롤러가 해당 요청을 처리할지 결정한다.
    • 핸들러 호출: 요청을 처리할 컨트롤러(핸들러)를 호출한다.
    • 모델과 뷰 결합: 컨트롤러가 반환한 모델 데이터를 뷰와 결합시켜 사용자에게 응답을 보낸다.

 

Spring MVC에서 어댑터 패턴의 역할

  • HandlerAdapter: Spring MVC에서 DispatcherServlet은 요청을 처리할 수 있는 적절한 핸들러를 찾고, 이를 처리할 수 있도록 HandlerAdapter를 사용하여 핸들러 메서드를 호출한다.
    • HandlerAdapter는 각기 다른 종류의 핸들러를 동일한 방식으로 처리할 수 있게 해준다.
    • 예를 들어, @Controller로 정의된 클래스의 메서드나, @RestController에서 반환하는 JSON을 처리하는 방식은 다를 수 있다. 이를 처리하는 HandlerAdapter가 각기 다르므로, DispatcherServlet은 핸들러와 상관없이 일관된 방식으로 요청을 처리할 수 있다.

3. Spring MVC 흐름

  1. 클라이언트 요청
    • 클라이언트(사용자)가 웹 브라우저나 다른 HTTP 클라이언트를 통해 HTTP 요청을 보낸다.
  2. DispatcherServlet (프론트 컨트롤러):
    • 모든 요청은 DispatcherServlet을 거친다.
    • DispatcherServlet은 요청을 처리할 수 있는 컨트롤러를 찾기 위해 HandlerMapping을 사용하여 적절한 컨트롤러를 찾는다.
  3. HandlerAdapter (어댑터):
    • DispatcherServlet은 요청을 처리할 수 있는 적절한 컨트롤러를 찾은 후, 이를 처리할 수 있도록 HandlerAdapter를 사용하여 핸들러 메서드를 호출한다.
    • HandlerAdapter는 각기 다른 종류의 컨트롤러(예: @Controller, @RestController)에 맞춰 요청을 처리하는 방식이 달라질 수 있기 때문에, 이를 하나의 공통된 인터페이스로 처리한다.
  4. Controller (컨트롤러):
    • 컨트롤러는 요청을 처리하고, 모델 데이터를 반환한다.
    • 반환된 모델 데이터는 ModelAndView 객체를 통해 전달될 수 있다.
  5. ViewResolver:
    • 컨트롤러가 반환한 뷰 이름을 ViewResolver가 실제 뷰 파일로 변환하여 사용자에게 응답을 전달한다.
  6. 응답 전달: 최종적으로 생성된 응답 페이지(예: HTML)는 클라이언트로 전달된다.

4. 핵심 구성 요소 정리

  • DispatcherServlet: 요청을 받아 적절한 핸들러를 찾아 호출하고, 그 결과를 사용자에게 반환하는 중앙 처리 장치.
  • HandlerMapping: 요청 URL에 매핑되는 컨트롤러를 찾아주는 컴포넌트.
  • Controller: 요청을 처리하고 결과를 반환하는 클래스.
  • ModelAndView: Controller가 반환하는 결과로, 모델 데이터와 뷰 정보를 포함한다.
  • ViewResolver: 논리적인 뷰 이름을 실제 뷰 파일로 변환해주는 컴포넌트.

 

예제

더보기

1. DispatcherServlet

  • web.xml 설정
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <!-- DispatcherServlet 설정 -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern> <!-- 모든 요청을 DispatcherServlet이 처리 -->
    </servlet-mapping>

</web-app>

 

 

2. HandlerAdapter

  • Spring에서는 기본적으로 HandlerAdapter가 @Controller와 @RequestMapping 어노테이션이 적용된 메서드를 자동으로 처리한다.
  • 이 설정은 기본적으로 Spring MVC의 설정 파일에 의해 제공된다.
<!-- spring-servlet.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- 컴포넌트 스캔을 통해 Controller 클래스 자동 탐지 -->
    <context:component-scan base-package="com.example.controller" />

    <!-- ViewResolver 설정 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

 

 

3. Controller

  • @Controller 어노테이션을 사용하여 요청을 처리하는 컨트롤러 클래스를 작성한다.
  • 이 클래스는 사용자가 요청한 URL을 처리하고, 필요한 데이터를 반환하는 역할을 한다.
  • ex. HomeController.java
package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {

    @RequestMapping("/home")
    public ModelAndView home() {
        // ModelAndView를 사용하여 모델 데이터와 뷰를 함께 반환
        ModelAndView modelAndView = new ModelAndView("home"); // "home" 뷰 이름
        modelAndView.addObject("message", "Spring MVC 예제입니다!");
        return modelAndView;
    }
}

 

 

4. ModelAndView

  • 위의 HomeController에서 ModelAndView를 사용하여 "home"이라는 뷰 이름과 "message"라는 데이터를 반환하고 있다.
  • 이 데이터는 JSP 뷰에서 표시된다.

 

5. ViewResolver

  • 컨트롤러에서 반환한 논리적인 뷰 이름을 실제 뷰 파일로 변환한다.
  • InternalResourceViewResolver를 사용하여 JSP 파일을 뷰로 렌더링할 수 있다.
  • spring-servlet.xml에서 ViewResolver 설정할 수 있다.
<!-- ViewResolver 설정 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

 

 

6. 뷰 파일 (home.jsp)

  • 컨트롤러에서 전달한 데이터를 출력할 뷰 파일이다.
  • ex. /WEB-INF/views/home.jsp
<html>
<head><title>Spring MVC 예제</title></head>
<body>
    <h1>${message}</h1>  <!-- Controller에서 전달한 message 출력 -->
</body>
</html>

5. Spring MVC 패턴의 장점

  • 유연성: 다양한 뷰 기술과 데이터베이스 기술을 지원하며, 필요에 따라 쉽게 확장할 수 있다.
  • 구조적 설계: MVC 패턴을 따르므로 코드의 분리가 잘 되어 있고, 유지보수성이 뛰어나다.
  • 편리한 요청 매핑: @RequestMapping, @GetMapping, @PostMapping 등의 어노테이션을 통해 요청 URL을 간편하게 매핑할 수 있다.
  • 테스트 용이성: Spring MVC는 테스트를 쉽게 할 수 있도록 설계되어 있어, 단위 테스트나 통합 테스트가 용이하다.