Part 6. 스프링 MVC의 Controller
6.4 Model이라는 데이터 전달자
- Controller의 메서드를 작성할 때 특별하게 Model이라는 타입을 파라미터로 지정할 수 있다.
- Model 객체는 JSP에 컨틀롤러에서 생성된 데이터를 담아서 전달하는 역할을 하는 존재다.
- 이를 이용해 JSP와 같은 뷰로 전달해야 하는 데이터를 담아 보낼 수 있다.
- 메서드의 파라미터에 Model 타입이 지정된 경우에는 스프링은 특별하게 Model 타입의 객체를 만들어서 메서드에 주입하게 된다.
- Model은 모델 2 방식에서 사용하는 request.setAttribute()와 유사한 역할을 한다.
- Servlet을 이용해 본 적 있다면 다음과 같은 코드에 익숙할 것이다.
< Servlet에서 모델 2 방식으로 데이터를 전달하는 방식 >
request.setAttribute("serverTime", new java.util.Date());
RequesetDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/home.jsp");
dispatcher.forward(request, response);
- 위의 코드를 스프링에서는 Model을 이용해 다음과 같이 처리한다.
public String home(Model model) {
model.addAttribute("serverTime", new java.util.Date());
return "home";
}
- 메서드의 파라미터를 Model 타입으로 선언하게 되면 자동으로 스프링 MVC에서 Model 타입의 객체를 만들어 주기 때문에 개발자의 입장에서는 필요한 데이터를 담아 주는 작업만으로 모든 작업이 완료된다.
- Model을 사용해야 하는 경우는 주로 Controller에 전달된 데이터를 이용해 추가적인 데이터를 가져와야 하는 상황이다.
- 예를 들어, 다음과 같은 경우들을 생각해 볼 수 있다.
- 리스트 페이지 번호를 파라미터로 전달받고, 실제 데이터를 View로 전달해야 하는 경우
- 파라미터들에 대한 처리 후 결과를 전달해야 하는 경우
6.4.1 @ModelAttribute 어노테이션
- 웹페이지의 구조는 Request에 전달된 데이터를 가지고 필요하다면 추가적인 데이터를 생성해 화면으로 전달하는 방식으로 동작한다.
- Model의 경우는 파라미터로 전달된 데이터는 존재하지 않지만 화면에서 필요한 데이터를 전달하기 위해 사용한다.
- 페이지 번호는 파라미터로 전달되자만, 결과 데이터를 전달하려면 Model에 담아 전달한다.
- 스프링MVC의 Controller는 기본적으로 Java Beans 규칙에 맞는 객체는 다시 화면으로 객체를 전달한다.
- Java Beans의 규칙은 단순히 생성자가 없거나 빈 생성자를 가져야 하며, getter/setter를 가진 클래스의 객체들을 의미한다.
- 앞의 예제에서 파라미터로 사용된 SampleDTO의 경우는 Java Bean의 규칙에 맞기 때문에 자동으로 다시 화면까지 전달된다.
- 전달될 때에는 클래스명의 앞글자는 소문자로 처리된다.
- 반면에 기본 자료형의 경우는 파라미터로 선언하더라도 기본적으로 화면까지 전달되지는 않는다.
< SampleController >
@GetMapping("/ex04")
public String ex04(SampleDTO dto, int page) {
log.info("dto: " + dto);
log.info("page: " + page);
return "/sample/ex04";
}
- ex04()는 SampleDTO 타입과 int 타입의 데이터를 파라미터로 사용한다.
- 결과를 확인하기 위해 '/WEB-INF/views' 폴더 아래 sample 폴더를 생성하고 리턴값에서 사용한 'ex04'에 해당하는 ex04.jsp를 작성한다.
< ex04.jsp >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C/DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>SAMPLEDTO ${sampleDTO }</h2>
<h2>PAGE ${page }</h2>
</body>
</html>
- 서버를 실행하고 브라우저를 통해 'http://localhost:8080/sample/ex04?name=aaa&age=11&page=9'와 같이 호출하면 화면에 SampleDTO만이 전달된 것을 확인할 수 있다.
- int 타입으로 선언된 page는 전달되지 않는다.

- @ModelAttribute는 강제로 전달받는 파라미터를 Model에 담아 전달하도록 할 때 필요한 어노테이션이다.
- @ModelAttribute가 걸린 파라미터는 타입에 관계없이 무조건 Model에 담아 전달되므로, 파라미터로 전달된 데이터를 다시 화면에서 사용해야 할 경우에 유용하게 사용된다.
- 기존 코드에서 int 타입의 데이터가 화면까지 전달되지 않았으므로 @ModelAttribute를 추가하면 다음과 같은 형태가 된다.
< SampleController >
@GetMapping("/ex04")
public String ex04(SampleDTO dto, @ModelAttribute("page") int page) {
log.info("dto: " + dto);
log.info("page: " + page);
return "/sample/ex04";
}
- @ModelAttribute가 붙은 파라미터는 화면까지 전달되므로 브라어를 통해 호출하면 아래와 같이 ${page}가 출력되는 것을 확인할 수 있다.(기본 자료형에 @Model Attribute를 적용할 경우에는 반드시 @ModelAttribute("page")와 같이 값을 지정하도록 한다.)

6.4.2 RedirectAttributes
- Model 타입과 더불어서 스프링 MVC가 자동으로 전달해 주는 타입 중에는 Redirect Attributes 타입이 존재한다.
- RedirectAttributes는 조금 특별하게도 일회성으로 데이터를 전달하는 용도로 사용된다.
- RedirectAttributes는 기존에 Servlet에서는 response.sendRedirect()를 사용할 때와 동일한 용도로 사용된다.
< Servlet에서 redirect 방식 >
response.sendRedirect("/home?name=aaa&age=10");
- 스프링 MVC를 이용하는 경우에는 다음과 같이 변경된다.
< 스프링 MVC를 이용하는 redirect 처리 >
rttr.addFlashAttribute("name", "AAA");
rttr.addFlashAttribute("age", 10);
return "redirect:/";
- RedirectAttributes는 Model과 같이 파라미터로 선언해서 사용하고, addFlashAttribute(이름, 값) 메서드를 이용해서 화면에 한 번만 사용하고 다음에는 사용되지 않는 데이터를 전달하기 위해 사용한다.
많은 도움이 되었습니다, 감사합니다.