- 요청으로부터 파라미터를 받을 때 하나의 값씩 받을 때는 일반적으로 @RequestParam을 사용한다. 하지만 이렇게 따로 받으면 불편하기 때문에 DTO를 만들어서 데이터를 주고 받는데, 이 때 @ModelAttribute를 사용하면 데이터를 쉽게 주고 받을 수 있다.
코드로 확인해보자
1. @RequestParam 사용시
- 먼저 @RequestParam을 활용하여 파라미터를 받아보자.
@PostMapping("/add")
public String addItemV1(@RequestParam String itemName,
@RequestParam int price,
@RequestParam Integer quantity,
Model model) {
Item item = new Item();
item.setItemName(itemName);
item.setPrice(price);
item.setQuantity(quantity);
itemRepository.save(item);
model.addAttribute("item", item);
return "basic/item";
}
- 파라미터 값이 넘어올 때 @RequestParam을 사용하면 파라미터 하나에 변수를 하나씩 생성해줘야 하고, 이 값을 뷰로 넘기려면 Model을 이용하여 데이터를 전송하기 때문에 번거로울 수 있다.
- 그렇다면 @ModelAttribute를 사용하면 파라미터를 어떻게 받을 수 있을까?
2. @ModelAttribute 사용시
@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item) {
itemRepository.save(item);
return "basic/item";
}
- Item이라는 DTO역할을 하는 클래스를 선언하여 객체 item으로 데이터를 주고 받는다.
@RequestParam이랑 비교하면 파라미터를 따로 받을 필요도 없고, Model을 호출하여 객체 바인딩을 할 필요도 없다.
@ModelAttribute("item") 이렇게 선언하면 Model에 item이라는 이름으로 객체를 넣어준다.
3. @ModelAttribute 객체 이름 생략
@PostMapping("/add")
public String addItemV3(@ModelAttribute Item item) {
itemRepository.save(item);
return "basic/item";
}
- 이 경우에는 객체의 첫 글자만 소문자로 치환하여 모델에 추가해준다.
예를 들어, 위처럼 Item의 경우 item으로, Hello의 경우 hello라는 이름으로 객체를 추가한다.
4. @ModelAttribute 생략
@PostMapping("/add")
public String addItemV4(Item item) {
itemRepository.save(item);
return "basic/item";
}
- 이 경우에도 3번과 마찬가지로 객체의 첫글자만 소문자로 치환하여 Model에 데이터를 추가해준다.
- 하지만 이 경우에는 파라미터값으로 받아오는 것인지를 구분하기 힘들 수 있기 때문에 비추천한다.
@ModelAttribute의 역할
- 요청 파라미터 처리
객체를 생성하고, 요청 파라미터의 값을 setter를 이용해 입력해준다.
- Model 추가
모델에 @ModelAttribute로 지정한 객체를 자동으로 넣어준다.
@ModelAttribute의 특별한 기능
@ModelAttribute("regions")
public Map<String, String> regions() {
Map<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
return regions;
}
- 이런식으로 컨트롤러에 @ModelAttribute를 사용한 메서드를 선언하게 되면, 해당 컨트롤러가 호출될 때마다 메서드가 실행되어 모델에 반환값을 넣어준다.
- 다만, 컨트롤러가 실행될 때마다 데이터를 생성하므로 최적화 측면에서 고려해야 할 점이 있다.