@RequestParam과 @ModelAttribute
@RequestParam vs @ModelAttribute
item
package hello.itemservice.domain.item;
import lombok.Data;
@Data
public class Item {
private Long id;
private String itemName;
private Integer price;
private Integer quantity;
public Item() {}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
1.@RequestParam
// 상품 등록
@PostMapping("/add")
public String addItemV1(@RequestParam String itemName,
@RequestParam int price,
@RequestParam int 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과 같은 경우 매개변수를 1:1 로 맵핑할 때 사용되는 어노테이션이다.
예를 들어 /add?itemName=가방&price=2000&qauntity=20 이런식으로 들어올 때 사용된다.
❗ @RequestParam을 사용했지만 Item이라는 객체를 매개변수로 활용하는 방식으로 사용하면 아래와 같은 에러가 발생한다.
// 상품 등록
@PostMapping("/add")
public String addItemV1(@RequestParam Item item, 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";
}
2.@ModelAttribute
// 상품 등록
@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item, Model model) {
itemRepository.save(item);
//model.addAttribute("item",item);
return "basic/item";
}
@ModelAttribute는 사용자가 요청시 전달하는 값을 오브젝트 형태로 매핑해주는 어노테이션이다.
예를 들어 itemName, price, qauntity를 인스턴스 변수로 가지는 Item 객체가 존재하고 이를 매개변수로 받기 위해서는 위와 같이 컨트롤러를 생성하고 /add?itemName=가방&price=2000&qauntity=20로 요청하면 각각의 값이 핸들러의 item 객체로 바인딩된다(이때 Setter가 반드시 필요하다)
@ModelAttribute 는 중요한 한가지 기능이 더 있는데, 바로 모델(Model)에 @ModelAttribute 로
지정한 객체를 자동으로 넣어준다. 지금 코드를 보면 model.addAttribute(“item”, item) 가 주석처리
되어 있어도 잘 동작하는 것을 확인할 수 있다.
모델에 데이터를 담을 때는 이름이 필요하다. 이름은 @ModelAttribute 에 지정한 name(value) 속성을사용한다.
만약 다음과 같이 @ModelAttribute 의 이름을 다르게 지정하면 다른 이름으로 모델에포함된다.
// 상품 등록
//@PostMapping("/add")
public String addItemV3(@ModelAttribute Item item, Model model) {
itemRepository.save(item);
// model.addAttribute("item",item); // 자동 추가, 생략 가능
return "basic/item";
}
// 상품 등록
//@PostMapping("/add")
public String addItemV4(Item item, Model model) {
itemRepository.save(item);
return "basic/item";
}
@ModelAttribute의 name 속성을 안주고 사용가능하다. 또한 @ModelAttribute는 생략도 가능하다.
@RequestParam과 @ModelAttribute의 차이
❓ @RequestParam과 @ModelAttribute의 가장 큰 차이점은 1:1 매핑이냐, 객체 매핑이냐의 차이이다. 그러면 여기서 의문이 들 수 있는데 @RequestParam으로 모두 받으면 되는데 왜 @ModelAttribute를 사용하는 것일까?
item
package hello.itemservice.domain.item;
import lombok.Data;
@Data
public class Item {
private Long id;
private String itemName;
private Integer price;
private Integer quantity;
private String color,
private Integer weight,
public Item() {}
public Item(String itemName, Integer price, Integer quantity, String color,Integer weight) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
this.color = color;
this.weight = weight;
}
}
기존의 item에서 color와 weight가 추가되었다.
@RequestParam
// 상품 등록
@PostMapping("/add")
public String addItemV1(@RequestParam String itemName,
@RequestParam int price,
@RequestParam int quantity,
@RequestParam String color,
@RequestParam Integer weight,
Model model) {
Item item = new Item();
item.setItemName(itemName);
item.setPrice(price);
item.setQuantity(quantity);
item.setColor(color);
item.setWeight(weight);
itemRepository.save(item);
model.addAttribute("item",item);
return "basic/item";
}
@RequestParam을 사용시 매개변수가 지속적으로 늘어나는데 이는 filed가 증가하면 지속적으로 매개변수가 늘어나는 문제점과 매개변수의 순서가 바뀔수 있다는 위험성이 생긴다.
따라서 위의 문제점들을 해결하기 위해서 @ModelAttribute를 사용한다.
Leave a comment