Зачем комбинация SessionAttributes с ModelAttribute
Зачем???По факту первое делает так чтобы элемент который добавлен в модель был виден во всей сессии, а второе делает так чтобы элемент указанный в параметрах ModelAttribute(который над методом) был добавлен в модель.Но ведь ModelAttribute вызывается всегда,значит элемент будет в модели всегда.Зачем их комбинация,если можно использовать одно из них??И то и то делает почти одно и то же .
Снизу пример комбинации
@RequestMapping("/store")
@SessionAttribute("form")
public class MenuController {
@ModelAttribute("form")
public Form createForm() {
return new Form();
}
@RequestMapping("/book")
public Sring bookList(@ModelAttribute("form") Form form){
//processing the form
}
}```
Ответы (2 шт):
Метод, помеченный аннотацией @ModelAttribute, автоматически добавляет в Model каждого метода, имеющего аннотацию @RequestMapping и ее производные, соответствующий объект, возвращаемый из такого метода (в приведенном примере - Form). Но этот объект - каждый раз новый, "чистый", если можно так выразиться, за исключением методов, где значение полей такого объекта заполняется через форму (html, jsp и т.д.).
Аннотация @SessionAttribute, в свою очередь, позволяет сохранять объект в spring-сессии (не путать с http-сессией!), т.е. если посредством какой-либо формы поля объекта, выступающего в качестве @ModelAttribute, были однажды заполнены, их значения будут доступны из любого метода в рамках того же контроллера, помеченного аннотацией @RequestMapping и ее производными, пока не будут принудительно очищены.
@SessionAttributes(names = {"form"})
public class MenuController {
@ModelAttribute("form")
public Form createForm() {
return new Form();
// 1) этот метод автоматически добавляет объект Form в Model,
// доступный из любого метода с аннотацией типа @RequestMapping
}
@PostMapping("/book")
public String createBooks(@ModelAttribute("form") Form form) {
// 2) здесь объект Form мог быть заполнен какими-то значениями через форму
return "bookPage";
}
@GetMapping("/book")
public String bookList(@ModelAttribute("form") Form form){
// 3) если метод вызван после метода в пункте 2 и в объекте Form появились какие-то значения,
// то здесь они будут доступны, т.е. объект Form не создастся заново пустой
return "bookListPage";
}
@GetMapping("/clear")
public String clear(SessionStatus status) {
status.setComplete();
// 4) таким способом можно очистить объект Form, если это необходимо по логике приложения
return "somePage";
}
}
Для наглядности можно почитать следующие статьи с Хабра и Baeldung
Небольшое уточнение. Метод, помеченный через аннотацию @ModelAttribute("form"), будет выполнен только, если атрибут "form" еще не создан - то есть null. Другими словами, при первом вызове формы он будет заполнен в new Form(). Больше вызываться не будет, так как на следующих шагах формы атрибут "form" уже будет существовать и далее он будет лишь постепенно заполняться в шагах формы.