@RequestParam과 @ModelAttribute

2 minute read

@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";
}

4.png


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를 사용한다.

Categories:

Updated:

Leave a comment