@ModelAttribute의 다른 용법
@ModelAttribute 메소드
@ModelAttribute
public void subjects(Model model) {
model.addAttribute("subjects", List.of("study", "seminar", "hobby", "social"));
}
@Controller
@SessionAttributes("event")
public class EventController {
@ModelAttribute
public void categories(Model model){
model.addAttribute("categories", List.of("study", "seminar", "hobby", "social"));
}
@GetMapping("/events/form/name")
public String eventsFormName(Model model) {
model.addAttribute("event", new Event());
// 자동으로 세션에 넣어줌
return "events/form-name";
}
@PostMapping("/events/form/name")
public String eventsFormNameSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "/events/form-name";
}
return "redirect:/events/form/limit";
}
@GetMapping("/events/form/limit")
public String eventsFormLimit(@ModelAttribute @Valid Event event, Model model) {
model.addAttribute("event", event);
// 자동으로 세션에 넣어줌
return "events/form-limit";
}
@PostMapping("/events/form/limit")
public String eventsFormLimitSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult, SessionStatus sessionStatus, RedirectAttributes attributes){
if(bindingResult.hasErrors()){
return "/events/form-limit";
}
sessionStatus.setComplete();
// 데이터베이스에서 save 했다고 가정
attributes.addFlashAttribute("newEvent", event);
return "redirect:/events/list";
}
@GetMapping("/events/list")
public String getEvents(Model model,
@SessionAttriubte LocalDateTime visitTime){
System.out.println(visitTime);
Event spring = new Event();
spring.setName("spring");
spring.setLimit(10);
Event newEvent = (Event) model.asMap().get("newEvent");
// 데이터베이스에서 읽어왔다고 가정한다.
List<Event> eventList = new ArrayList<>();
eventList.add(spring);
eventList.add(newEvent);
model.addAttribute("eventList", eventList);
return "/events/list";
}
}
또는 void가 아니라 List를 리턴할 수 있다. 이러한 경우에는 이름을 지정해 주어야 한다.
@Controller
@SessionAttributes("event")
public class EventController {
@ModelAttribute("categories")
public List<String> categories(Model model) {
return List.of("study", "seminar", "hobby", "social");
}
@GetMapping("/events/form/name")
public String eventsFormName(Model model) {
model.addAttribute("event", new Event());
// 자동으로 세션에 넣어줌
return "events/form-name";
}
@PostMapping("/events/form/name")
public String eventsFormNameSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "/events/form-name";
}
return "redirect:/events/form/limit";
}
@GetMapping("/events/form/limit")
public String eventsFormLimit(@ModelAttribute @Valid Event event, Model model) {
model.addAttribute("event", event);
// 자동으로 세션에 넣어줌
return "events/form-limit";
}
@PostMapping("/events/form/limit")
public String eventsFormLimitSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult, SessionStatus sessionStatus, RedirectAttributes attributes){
if(bindingResult.hasErrors()){
return "/events/form-limit";
}
sessionStatus.setComplete();
// 데이터베이스에서 save 했다고 가정
attributes.addFlashAttribute("newEvent", event);
return "redirect:/events/list";
}
@GetMapping("/events/list")
public String getEvents(Model model,
@SessionAttriubte LocalDateTime visitTime){
System.out.println(visitTime);
Event spring = new Event();
spring.setName("spring");
spring.setLimit(10);
Event newEvent = (Event) model.asMap().get("newEvent");
// 데이터베이스에서 읽어왔다고 가정한다.
List<Event> eventList = new ArrayList<>();
eventList.add(spring);
eventList.add(newEvent);
model.addAttribute("eventList", eventList);
return "/events/list";
}
}
테스트 코드
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void getEvents() throws Exception{
Event newEvent = new Event();
newEvent.setName("Winter is coming.");
newEvent.setLimit(10000);
mockMvc.perform(get("/events/list")
.sessionAttr("visitTime", LocalDateTime.now())
.flashAttr("newEvent", newEvent))
.andDo(print())
.andExpect(status().isOk())
.andExpect(model().attributeExists("categories"))
// HTML 본문 테스트
.andExpect(xpath("//p").nodeCount(2));
}
}
테스트 코드를 돌려보면 model 정보에 categories가 추가된 걸 확인할 수 있다.
또한 @RequestMapping과 같이 사용하면 해당 메소드에서 리턴하는 객체를 모델에 넣어 준다. String이 아닌 객체를 리턴하는 경우에는 RequestToViewNameTranslator가 뷰를 찾아준다.
@Controller
@SessionAttributes("event")
public class EventController {
@ModelAttribute
public void categories(Model model){
model.addAttribute("categories", List.of("study", "seminar", "hobby", "social"));
}
@GetMapping("/events/form/name")
@ModelAttribute // 생략 가능
public Event eventsFormName() {
// 여기서 리턴하는 객체를 model에 담아준다.
return new Event();
}
@PostMapping("/events/form/name")
public String eventsFormNameSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "/events/form-name";
}
return "redirect:/events/form/limit";
}
@GetMapping("/events/form/limit")
public String eventsFormLimit(@ModelAttribute @Valid Event event, Model model) {
model.addAttribute("event", event);
// 자동으로 세션에 넣어줌
return "events/form-limit";
}
@PostMapping("/events/form/limit")
public String eventsFormLimitSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult, SessionStatus sessionStatus, RedirectAttributes attributes){
if(bindingResult.hasErrors()){
return "/events/form-limit";
}
sessionStatus.setComplete();
// 데이터베이스에서 save 했다고 가정
attributes.addFlashAttribute("newEvent", event);
return "redirect:/events/list";
}
@GetMapping("/events/list")
public String getEvents(Model model,
@SessionAttriubte LocalDateTime visitTime){
System.out.println(visitTime);
Event spring = new Event();
spring.setName("spring");
spring.setLimit(10);
Event newEvent = (Event) model.asMap().get("newEvent");
// 데이터베이스에서 읽어왔다고 가정한다.
List<Event> eventList = new ArrayList<>();
eventList.add(spring);
eventList.add(newEvent);
model.addAttribute("eventList", eventList);
return "/events/list";
}
}
참고