728x90
스프링 프레임워크에서는 컨트롤러(Controller)에서 뷰(View)로 데이터를 전달하는 여러 가지 방법이 있다.
그 예로는 Model, ModelMap, ModelAndView가 있다.
개념과 차이점을 알아보자.
1. 개념
1) Model
- Model이란?
👉 뷰를 렌더링하는 데 사용되는 속성을 제공할 수 있는 가장 기본적인 개념
(스프링 MVC에서 컨트롤러와 뷰 사이의 데이터를 전달하는 역할을 하는 인터페이스) - 뷰에 데이터를 제공하려면?
👉 controller에서 데이터를 Model 객체에 추가하면, 이 Model 객체는 뷰로 전달되어서 뷰에서 사용될 수 있음 - Model에 데이터를 추가하는 방법
👉 addAttribute() 메서드를 사용
예) model.addAttribute("message", "Hello, World!"); - 속성이 있는 맵을 Model 인스턴스와 병합할 수 있음
@GetMapping("/showViewPage")
public String passParameterWithModel(Model model) {
Map<String, String> map = new HashMap<>();
map.put("spring", "mvc");
model.addAttribute("message", "WantToGoHome");
//Model mergeAttributes(Map<Key, Value>): Map에 포함된 <키, 값>을 현재 모델에 추가
model.mergeAttributes(map);
return "view/viewPage";
}
2) ModelMap
- ModelMap이란?
👉 Model 인터페이스를 구현한 클래스. Map과 유사한 API를 제공함 - 특징
- Model 인터페이스와 마찬가지로 ModelMap도 뷰를 렌더링하는 데 사용되는 값을 전달하는 데 사용됨
- Model 인터페이스와 마찬가지로 ModelMap에 데이터를 추가하려면 addAttribute를 사용
- 장점
- 값을 컬렉션으로 전달하고, 이러한 값들을 마치 맵 내에 있는 것처럼 처리할 수 있음
@GetMapping("/printViewPage")
public String passParametersWithModelMap(ModelMap map) {
map.addAttribute("welcomeMessage", "welcome");
map.addAttribute("message", "WantToGoHome");
return "view/viewPage";
}
3) ModelAndView
- ModelAndView란?
👉 값을 뷰로 전달하는 인터페이스. 스프링 MVC에 필요한 모든 정보를 한 번에 반환할 수 있음 - 특징
- ModelAndView 객체를 생성하고, 이 객체에 데이터와 뷰 이름을 설정한 후 컨트롤러에서 반환하면, 스프링 MVC는 이 ModelAndView 객체를 사용하여 뷰를 렌더링 함
- 장점
- Model과 View를 한 번에 처리할 수 있으므로, 편리하게 사용할 수 있음
@GetMapping("/goToViewPage")
public ModelAndView passParametersWithModelAndView() {
ModelAndView modelAndView = new ModelAndView("view/viewPage");
modelAndView.addObject("message", "WantToGoHome");
return modelAndView;
}
2. 컨트롤러는 각각을 언제 사용해야 할까?
- 단순히 데이터를 전달하는 경우에는 Model이나 ModelMap
뷰 이름과 함께 데이터를 전달하려면 ModelAndView 사용 - HTTP 요청 파라미터를 객체에 바인딩하거나 특정 메소드의 반환값을 모델에 추가하고 싶다면 @ModelAttribute 사용
3. ModelAttribute
- 역할: HTTP 요청 파라미터를 자바 객체에 바인딩
- 특징
- @ModelAttribe 어노테이션이 붙은 메서드가 반환하는 것은 뷰가 아닌 데이터
- 이 메서드가 반환하는 데이터는 자동으로 모델에 추가되며, 이 모델은 뷰를 렌더링 하는 데 사용됨
- 스프링 MVC에서는 컨트롤러 메서드가 반환하는 값이 기본적으로 뷰 이름으로 해석되지만,
@ModelAttribute 어노테이션이 붙은 메서드는 예외
👉 @ModelAttribute 어노테이션이 붙은 메서드는 뷰 이름을 반환하는 것이 아니라, 뷰에서 사용할 수 있는 데이터를 반환함 - @ModelAttribue 어노테이션이 붙은 메서드는 해당 컨트롤러의 모든 @RequestMapping 메서드가 호출되기 전에 자동으로 호출됨
👉 이 메서드가 반환하는 데이터는 해당 컨트롤러의 모든 뷰에서 사용할 수 있음
[사용 방법]
- (1) 메서드 파라미터에 적용
- @ModelAttribute가 붙은 메서드 파라미터는 HTTP 요청 파라미터를 해당 객체에 바인딩하는 역할을 함. 이는 주로 폼 데이터를 객체로 받아오는 경우에 사용됨
- 예) 사용자로부터 받은 사용자 정보를 User 객체에 바인딩하기
@PostMapping("/user")
public String submit(@ModelAttribute User user) {
// user 객체는 요청 파라미터를 바인딩 받은 상태
// 비즈니스 로직
return "userView";
}
- (2) 메서드 자체에 적용
- @ModelAttribute가 붙은 메소드는 뷰가 렌더링 되기 전에 항상 먼저 실행되며,
이 메소드의 반환값이 모델에 추가됨
👉 이를 통해 여러 뷰에서 공통으로 사용되는 참조 데이터를 제공하는 데 유용함 - 예) 모든 뷰에서 사용 가능한 설정 정보 제공
- @ModelAttribute가 붙은 메소드는 뷰가 렌더링 되기 전에 항상 먼저 실행되며,
@ModelAttribue("settings")
public Settings getSettings() {
return settingService.getSettings();
}
이 경우, getSettings() 메서드가 반환하는 Settings 객체는 "settings"라는 이름으로 모델에 자동으로 추가되며,
뷰에서는 이 "settings" 속성을 사용하여 설정 정보에 접근할 수 있다.
4. @ControllerAdvice와 @ModelAttribue
- 관계
- @ControllerAdvice 어노테이션과 @ModelAttribue 어노테이션을 함께 사용하면 모든 컨트롤러에서 공통으로 사용되는 모델 속성을 정의할 수 있음
- @ControllerAdvice 어노테이션이 붙은 클래스는 모든 컨트롤러에 대해서 공통적으로 적용되는 코드를 정의하는 데 사용됨
- @ControllerAdvice를 적용한 클래스 내부에서 @ModelAttribute 어노테이션을 사용하면, 해당 속성이 모든 컨트롤러와 뷰에서 적용되어 사용할 수 있음
@ControllerAdvice
public class GlobalControllerAdvice {
@ModelAttribute("settings")
public Settings getSettings() {
return settingsService.getSettings();
}
}
이 경우, getSettings() 메소드가 반환하는 Settings 객체는 "settings"라는 이름으로 모델에 추가되며, 이 모델은 모든 컨트롤러의 모든 뷰에서 사용할 수 있다.
👉 @ControllerAdvice와 @ModelAttribute를 함께 사용하면, 애플리케이션 전체에서 공통으로 사용되는 모델 속성을 한 곳에서 처리할 수 있다.
👉 코드의 중복 감소, 유지 및 관리 용이
- @ModelAttribute vs @ControllerAdvice + @ModelAttribute
@ModelAttribute를 일반 컨트롤러 클래스 안에 선언하는 경우와
@ControllerAdvice 클래스 안에 선언하는 경우의 주요 차이점은 적용 범위이다.
- 일반적인 컨트롤러 클래스에서의 @ModelAttribute 사용
- 해당 컨트롤러의 @RequestMapping 메소드가 호출되기 전에 먼저 호출됨
- 👉 이 메소드가 반환하는 객체는 해당컨트롤러의 모든 뷰에서 사용할 수 있음
- 그러나 이 객체는 해당 컨트롤러에서만 사용할 수 있으며, 다른 컨트롤러에서는 사용할 수 없음
- 장점: 각 컨트롤러에서 필요한 모델 속성을 직접 관리 가능
- 단점: 같은 모델 속성이 여러 컨트롤러에서 필요한 경우 코드의 중복 발생 가능
- @ControllerAdvice 클래스에서의 @ModelAttribute 사용
- 모든 컨트롤러의 @RequestMapping 메소드가 호출되기 전에 먼저 호출됨
👉 이 메소드가 반환하는 객체는 모든 컨트롤러의 모든 뷰에서 사용 가능 - 장점: 애플리케이션 전체에서 공통으로 사용되는 모델 속성을 한 곳에서 관리
👉 코드의 중복 감소, 유지 관리 용이 - 단점: 모든 컨트롤러와 뷰에서 이 모델 속성이 사용 가능하므로, 필요하지 않은 경우에도 이 메소드가 호출되고 모델 속성이 생성될 수 있음
- 모든 컨트롤러의 @RequestMapping 메소드가 호출되기 전에 먼저 호출됨
- 결론
- 공통으로 사용되는 모델 속성이 많은 경우 @ControllerAdvice 사용
- 각 컨트롤러에서 고유한 모델 속성을 관리해야 하는 경우, 일반 컨트롤러 클래스에서 @ModelAttribute를 사용
참고
https://velog.io/@wlsdks12/Spring-MVC-Model-ModelAndView-ModelMap
728x90
'Web > Spring' 카테고리의 다른 글
[Spring] Spring MVC란? (1) | 2024.05.03 |
---|---|
[Spring] JDBC 프로그래밍을 위한 API와 용어들 (0) | 2024.04.30 |
[Spring] 컴포넌트 스캔 Component Scan (0) | 2024.04.17 |
[Spring] DI 자동주입 (0) | 2024.04.14 |
[Spring] 의존성 주입과 제어 역행 (4) | 2024.04.10 |