Я не совсем понимаю, как использовать @SessionAttributes - PullRequest
19 голосов
/ 06 февраля 2011

Я пытаюсь понять архитектуру Spring MVC.Тем не менее, я полностью сбит с толку поведением @ SessionAttributes.

Пожалуйста, посмотрите на SampleController ниже, он обрабатывает метод post с помощью класса SuperForm.На самом деле, просто поле класса SuperForm привязывается только так, как я и ожидал.

Однако, после того как я поместил @SessionAttributes в Controller, метод обработки связывается как SubAForm.Кто-нибудь может объяснить мне, что произошло в этом переплете.

-------------------------------------------------------

@Controller
@SessionAttributes("form")
@RequestMapping(value = "/sample")
public class SampleController {

    @RequestMapping(method = RequestMethod.GET)
    public String getCreateForm(Model model) {
        model.addAttribute("form", new SubAForm());
        return "sample/input";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String register(@ModelAttribute("form") SuperForm form, Model model) {
        return "sample/input";
    }
}

-------------------------------------------------------

public class SuperForm {

    private Long superId;

    public Long getSuperId() {
        return superId;
    }

    public void setSuperId(Long superId) {
        this.superId = superId;
    }

}

-------------------------------------------------------

public class SubAForm extends SuperForm {

    private Long subAId;

    public Long getSubAId() {
        return subAId;
    }

    public void setSubAId(Long subAId) {
        this.subAId = subAId;
    }

}

-------------------------------------------------------

<form:form modelAttribute="form" method="post">
    <fieldset>
        <legend>SUPER FIELD</legend>
        <p>
            SUPER ID:<form:input path="superId" />
        </p>
    </fieldset>
    <fieldset>
        <legend>SUB A FIELD</legend>
        <p>
            SUB A ID:<form:input path="subAId" />
        </p>
    </fieldset>
    <p>
        <input type="submit" value="register" />
    </p>
</form:form>

Ответы [ 4 ]

24 голосов
/ 06 февраля 2011

При обработке POST запроса Spring делает следующее:

  • Без @SessionAttributes: Spring создает новый экземпляр SuperForm (тип выводится из сигнатуры register()), заполняет его свойства значениями из полей формы и передает его в метод register().

  • С @SessionAttributes: Spring получает экземпляр атрибута модели из сеанса(куда он был помещен при обработке GET из-за наличия @SessionAttributes), обновляет свои свойства по значениям из полей from и передает его методу register().

То есть с @SessionAttributes, register() получает тот же экземпляр объекта атрибута модели, который был помещен в модель с помощью getCreateForm().

3 голосов
/ 06 февраля 2011

Добавление к тому, что сказал @axtavt: Предположим, в getCreateForm вы помещаете некоторые значения для раскрывающегося списка (список или карта), или вы кладете некоторые значения в форму, которую вы хотите в методе регистра, но нене хочу, чтобы они отображались в форме (даже в скрытых полях).Теперь предположим, что в методе register произошла ошибка, и вам нужно снова показать форму.Чтобы заполнить выпадающие значения и другие значения, которые вам понадобятся в следующем посте, вам придется заполнить их в форме.@SessionAttribute помогает здесь как @axtavt, очень хорошо описанный выше.

0 голосов
/ 25 декабря 2018

Согласно справочной документации Spring @ModelAttribute аргумент аннотированного метода разрешается следующим образом:

  • Получить из объекта модели, если он присутствует (обычно добавляется с помощью @ModelAttribute аннотированных методов)
  • Получить из сеанса HTTP, используя @SessionAttributes.
  • Создать, используя переменную пути URI, которая соответствует имени @ModelAttribute через конвертер
  • Создать с помощью конструктора по умолчанию и добавить его в Model.

Класс обработчика может быть аннотирован с помощью @SessionAttributes со списком имен в качестве аргументов. Это необходимо для того, чтобы Spring сохранил (в сеансе) те элементы данных, присутствующие в данных модели, которые соответствуют именам, указанным в аннотации @SessionAttributes.

Таким образом, в SampleController аргумент @ModelAttribute метода post разрешается с полем @SessionAttributes из-за метода разрешения, упомянутого выше.

0 голосов
/ 06 ноября 2013
@Controller
@SessionAttributes("test")
public class Controller{
    Customer customer;

    public Controller() {
        super();
        customer = new Customer();
    }

    @ModelAttribute("test")
    public Customer getCustomer() {
       customer.setName("Savac");
       return customer;
    }

    @RequestMapping({"/index"})
    public ModelAndView showMainPage (@ModelAttribute("test") Customer customer, ModelMap model, method = RequestMethod.GET) {
        //in the view you set the name
        return new ModelAndView("index");
    }

    @RequestMapping(value = "customer/{customerID}", method = RequestMethod.GET)
    public ModelAndView viewAdvice(@PathVariable("customerID") int customerID, @ModelAttribute("test") Customer customer, ModelMap model) {
        customer.setName("AnotherName");
        model.addAttribute("test", customer);
        return new ModelAndView("customer");
    }

}
...