결론 : @Controller 클래스 안에 여러 요청 메서드가 있을 것인데, 아래와 같이 @ModelAttribute을 붙이고 그 메서드를 정
의하면 그 어떤 요청 메서드가 호출이 되더라도 Model 객체에 자동으로 등록이 된다.
-> 컨트롤러 클래스의 여러 요청 메서드에서 Model 객체에 등록해야 할 데이터가 중복될 때 매우 유용하다.
package hello.itemservice.web.form;
import hello.itemservice.domain.item.Item;
import hello.itemservice.domain.item.ItemRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Controller
@RequestMapping("/form/items")
@RequiredArgsConstructor
public class FormItemController {
private final ItemRepository itemRepository;
@ModelAttribute("regions")
public Map<String,String> regions(){
LinkedHashMap<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL","서울");
regions.put("BUSAN","부산");
regions.put("JEJU","제주");
return regions;
}
@GetMapping
public String items(Model model) {
List<Item> items = itemRepository.findAll();
model.addAttribute("items", items);
return "form/items";
}
@GetMapping("/{itemId}")
public String item(@PathVariable long itemId, Model model) {
Item item = itemRepository.findById(itemId);
model.addAttribute("item", item);
/**
* @ModelAttribute("regions")
* public Map<String,String> regions()로 대체
*/
/*LinkedHashMap<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL","서울");
regions.put("BUSAN","부산");
regions.put("JEJU","제주");
model.addAttribute("regions",regions);*/
return "form/item";
}
@GetMapping("/add")
public String addForm(Model model) {
model.addAttribute("item",new Item());
/**
* @ModelAttribute("regions")
* public Map<String,String> regions()로 대체
*/
/* LinkedHashMap<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL","서울");
regions.put("BUSAN","부산");
regions.put("JEJU","제주");
model.addAttribute("regions",regions);*/
return "form/addForm";
}
@PostMapping("/add")
public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) {
log.info("item.open() = {}",item.getOpen());
Item savedItem = itemRepository.save(item);
redirectAttributes.addAttribute("itemId", savedItem.getId());
redirectAttributes.addAttribute("status", true);
return "redirect:/form/items/{itemId}";
}
@GetMapping("/{itemId}/edit")
public String editForm(@PathVariable Long itemId, Model model) {
Item item = itemRepository.findById(itemId);
model.addAttribute("item", item);
/**
* @ModelAttribute("regions")
* public Map<String,String> regions()로 대체
*/
/*LinkedHashMap<String, String> regions = new LinkedHashMap<>();
//LinkedHashMap을 사용하면 put한 [순서대로] 저장이 된다.
regions.put("SEOUL","서울"); // 삽입 순서 1
regions.put("BUSAN","부산"); // 삽입 순서 2
regions.put("JEJU","제주"); // 삽입 순서 3
model.addAttribute("regions",regions);*/
return "form/editForm";
}
@PostMapping("/{itemId}/edit")
public String edit(@PathVariable Long itemId, @ModelAttribute Item item) {
itemRepository.update(itemId, item);
return "redirect:/form/items/{itemId}";
}
}
단, 성능 최적화 부분에서 고려해야 할 점이 있다.
@ModelAttribute 메서드는 한 번만 호출이 되는 것이 아니라 요청 메서드가 호출될 때마다 새롭게 호출이 된다.
이렇게 되면 부하가 많이 생긴다.
만약 Map 컬렉션에 담기는 내용이 동적으로 변하지 않거나 하면 static 등으로 정의하여 정말 필요로 하는 요청 메서드에서
만 호출하여 쓸 수 있도록 하는 것도 하나의 성능 최적화의 방법이다.
'Springあるある' 카테고리의 다른 글
BindingResult의 동작 (0) | 2025.01.14 |
---|---|
input 태그 속에 th:field와 th:value가 동시에 있는 경우 (0) | 2025.01.10 |
@RequiredArgsConstructor vs @AllArgsConstructor (0) | 2025.01.10 |
[타임리프와 스프링의 통합]의 진짜 의미! (0) | 2025.01.10 |
Map :: values() 사용 시 주의점(Feat. ConcurrentModificationException) (0) | 2025.01.10 |