빡코

[개념] MVC 패턴_데이터의 흐름 본문

Java/Spring Framework

[개념] MVC 패턴_데이터의 흐름

chris.djang 2020. 1. 29. 15:50

 

스프링 MVC의 핵심 구성 요소 

 

DistpatcherServlet

웹 브라우저의 요청을 받기 위한 창구 역할, 다른 주요 구성 요소들을 이용해서 요청 흐름을 제어하는 역할을 한다.

-모든 연결을 담당

HandlerMapping

클라이언트의 요청을 처리할 핸들러 객체를 찾아준다

-웹 요청 경로가 '/hello'라면 등록된 컨트롤러 중에서 '/hello'요청 경로를 처리할 컨트롤러를 리턴한다. 

HandlerAdapter

-DispatcherServlet과 핸들러 객체 사이의 변화을 알맞게 처리해준다. 

-DispatcherServlet은 HandlerMappring이 찾아준 컨트롤러 객체를 처리할 수 있는 HandlerAdapter빈에게 요청처리를 위임

-HandlerAdapter는 컨트롤러에 알맞은 메서드롤 호출해서 요청을 처리하고, 결과를 DispatcherServlet에 리턴함 

-HandlerAdapter는 컨트롤러의 처리결과를 ModelAndView라는 객체를 변환해서 DispatcherServlet리턴함

ViewResolver

요청처리결과를 생성할 때, View를 찾아주고,  View는 최종적으로 클라이언트에 응답을 생성하여 전달한다. 

-ModelAndView는 컨트롤러가 리턴한 뷰 이름을 담고 있는데, 이 뷰 이름에 해당하는 View객체를 찾거나 생성하여 리턴한다

-응답을 생성하기 위해 JSP를 사용하는 ViewResolver는 매번 새로운  view 객체를 생성해서 DispatcherServlet에 리턴한다. 

 

컨트롤러와 핸들러 

클라이언트의 요청을 실제로 처리하는 것은 컨트롤러이고, DispatcherServlet은 클라이언트 요청을 전달받는 창구역할

 

왜 HandlerMapping 객체가 Controller를 찾아주는 타입일까? 

-DispatcheServlet 입장에서는 클라이언트 요청을 처리하는 객체의 타입이 반드시 @Controller를 적용할 클래스일 필요는 없다. 실제로 스프링이 클라이언트 요청을 처리하기 위해 제공하는 타입중에는 HttpRequestHandler도 존재함. 

-즉, 스프링 MVC는 웹 요청을 실제로 처리하는 객체를 핸들러(Handler)라고 표현하고 있으며, @Controller 적용 객체나 Controller 인터페이스를 구현한 객체는 모두 스프링  MVC입장에서는 핸들러가된다. 따라서, 특정 요청 경로를 처리해주는 핸들러를 찾아주는 객체를 HandlerMapping이라고 부른다. 

 

-DispatcherServlet은 핸들러 객체의 실제타입에 상관없이 실행결과를 ModelAndView라는 타입으로만 받을 수 있으면 됨

-핸들러의 처리결과를 ModelAndView로 변환해주는 객체가 필요하며, HandlerAdapter가 이 변환을 처리해줌 

 

@Controller를 위한 HandlerMapping과 HandlerAdapter

import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();

    }

    @Override
    public void configureViewResolvers(
            ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/view/",".jsp");

    }
}

@EnableWebMvc이란?

이 태그 안에는 @Controller타입의 핸들러 객체를 처리하기 위한 두 클래스가 포함되어 있음

-~RequestMappingHandlerMapping: @Controller 어노테이션이 적용된 객체의 요청을 매핑 어노테이션(@GetMapping)값을 이용해서 웹 브라우저 처리할 컨트롤러 빈을 찾는다.

-~RquestMappingHandlerAdapter : 컨트롤러의 메서드를 알맞게 실행하고, 그 결과를 ModelAndView 객체로 변환해서 Dispatcher에 리턴한다. 

-@EnableWebMvc 어노테이션을 사용하면 @Controller 어노테이션을 붙인 컨트롤러를 위한 설정을 생성한다. 

 

@Configuration

@Configuration 어노테이션이 붙은 클래스 역시 컨테이너에 빈으로 등록이되므로 MvcConfig클래스는 WebConfigurer 타입의 빈이된다. 

package com.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model,
                        @RequestParam(value = "name", required = false) String name) {
            model.addAttribute("greeting","안녕하세요"+name);
            return "hello";
        }

    }

RequestMappingHandlerAdapter 클래스 "/hello" 요청 경로에 대해 hello() 메소드를 호출한다. 

이때 모델 객체를 생성해서 첫번째 파라미터로 전달, "name"인 HTTP요청 파라미터 값을 두번째 파라미터로 전달한다

RequestMappingHandlerAdapter는 컨트롤러 메서드 겱과 값이 String 타입이면 해당 값을 뷰 이름으로 갖는 ModelAndView 객체를 생성해서 DispatcherSevlet에 리턴한다. 이때 첫번째 파라미터로 전달한 Model 객체에 보관된 값도 ModelAndView와 함께 전달한다.