Spring Model 객체: 컨트롤러에서 뷰로 데이터 전달

Model 객체

Spring MVC의 `Model` 객체는 컨트롤러에서 뷰로 데이터를 전달하는데 사용하는 객체입니다. Model 객체는 컨트롤러 메서드의 파라미터로 선언되어 사용됩니다. 컨트롤러에서 데이터를 추가하면, 해당 데이터는 뷰에서 참조할 수 있게 됩니다.

 

아래는 `Model` 객체를 파라미터로 받아 `addAttribute()`로 데이터를 추가하고, 해당 데이터를 `dataView`라는 뷰에서 참조할 수 있게 하는 예제 코드 입니다.

@Controller
public class MyController {
  
  @RequestMapping("/getData")
  public String getData(Model model) {
    model.addAttribute("name", "Kim");
    model.addAttribute("age", 25);
    return "dataView";
  }
}

Model 객체 주요 메서드

  • addAttribute(String attributeName, Object attributeValue): 데이터를 추가합니다. attributeName은 데이터의 이름, attributeValue는 데이터의 값입니다. 이렇게 추가된 데이터는 뷰에서 ${attributeName} 형식으로 참조할 수 있습니다.
  • addAllAttributes(Map<String, ?> attributes): Map 형태의 데이터를 일괄적으로 추가합니다.
  • mergeAttributes(Map<String, ?> attributes): 기존의 모델 데이터와 주어진 Map의 데이터를 병합합니다. 만약 동일한 이름의 데이터가 이미 존재한다면, 주어진 데이터로 대체됩니다.
  • containsAttribute(String attributeName): 주어진 이름의 데이터가 모델에 포함되어 있는지 확인합니다.
  • asMap(): Model 객체를 Map 형태로 반환합니다.

@ModelAttribute

컨트롤러 → 뷰 데이터 전달

@Controller
public class MyController {

  @ModelAttribute("data")
  public String myData() {
    return "myData";
  }

  @GetMapping("/hello")
  public String hello(Model model) {
    return "hello";
  }
}

`@ModelAttribute`가 붙은 메소드에서 Model에 담는 과정을 처리하여 코드가 단순해집니다.

사용 방법은 컨트롤러 메서드에 `@ModelAttribute` 어노테이션을 추가해 주어야 합니다. 해당 어노테이션을 부여한 메서드가 있으면 핸들러 메서드가 호출되기 전에 먼저 실행되어 Model에 데이터가 담겨 있게 됩니다.

 

`@ModelAttribute`에 `value` 속성을 지정하면 해당 이름으로 데이터가 저장되지만 `value` 속성을 지정하지 않으면, 메서드 이름의 첫 글자를 소문자로 변환한 값을 이름으로 하여 Model에 담깁니다.

 

뷰 → 컨트롤러 데이터 전달

`@ModelAttribute`는 요청 파라미터나 경로 변수를 바인딩하고 해당 값을 모델에 추가할 수도 있습니다. 이를 통해 폼 데이터를 객체로 변환하거나, 요청 파라미터를 특정 객체의 필드에 매핑할 수 있습니다. 아래는 `@ModelAttribute`를 사용하기전 기존 코드입니다.

@RequestMapping("/user/search")
public String search(@RequestParam int id, @RequestPara String name, @RequestPatam String email
		Model model){
	List<User> list = userService.search(id, name, email);
	model.addAttribute("userList",list);
	// ...
}

컨트롤러 메서드의 매개변수 앞에 `@ModelAttribute` 어노테이션을 추가하고 바인딩할 객체를 지정합니다. 요청 파라미터 이름과 객체의 필드 이름이 일치하는 경우 자동으로 바인딩됩니다.

//@ModelAttribute 적용
@RequestMapping("/user/search")
public String search(@ModelAttribute UserSearch userSearch){
	List<User> list = userService.search(userSearch);
	model.addAttribute("userList",list);
	// ...
}

`@ModelAttribute`를 통해 자동으로 바인딩 됨을 확인할 수 있습니다. `@ModelAttribute`나 `value` 속성을 생략할 수 있으며 생략 시 매개변수의 이름과 동일한 이름의 객체가 모델에 자동으로 추가됩니다.

 


Map

@Controller
public class MyController {
  
  @RequestMapping("/getData")
  public String getData(Map<String, Object> map) {
    map.put("name", "Kim");
    map.put("age", 25);
    return "dataView";
  }
}

`Map`을 사용하여 데이터를 전달할 수도 있습니다.

사실 `Model`은 `java.util.Map`의 구현체이기 때문입니다. `Model`을 사용하여 데이터를 전달하는 이유는 뷰로 전달되는 데이터의 의미를 명확하게 표현하고(명시성) Spring MVC의 테스트 기능을 활용하기에 용이하기 때문입니다.