我对如何使用@SessionAttributes感到困惑

时间:2011-02-06 15:05:52

标签: spring spring-mvc session-variables

我试图了解Spring MVC的架构。但是,我完全被@SessionAttributes的行为搞糊涂了。

请看下面的SampleController,它是由SuperForm类处理post方法。事实上,只是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 个答案:

答案 0 :(得分:24)

处理POST请求时,Spring会执行以下操作:

  • 没有@SessionAttributes:Spring实例化SuperForm的新实例(类型是从register()的签名推断出来的),通过表单字段和传递中的值填充其属性它是register()方法。

  • 使用@SessionAttributes:Spring从会话中获取模型属性的实例(由于存在GET而在处理@SessionAttributes时放置它的位置),通过以下方式更新其属性来自字段的值并将其传递给register()方法。

也就是说,使用@SessionAttributesregister()获取由getCreateForm()放入模型的模型属性对象的相同实例。

答案 1 :(得分:3)

添加到@axtavt所说的内容:假设在getCreateForm中你为下拉列表(列表或映射)添加了一些值,或者你在寄存器方法中放置了一些你需要的值但是你不希望它们以表格形式显示(甚至不在隐藏的字段中)。现在假设register方法中发生错误,您需要再次显示该表单。要填充下一篇文章中需要的下拉值和其他值,您必须在表单中重新填充它们。 @SessionAttribute有助于@axtavt,如上所述。

答案 2 :(得分:0)

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

}

答案 3 :(得分:0)

根据Spring参考文档@ModelAttribute注释的方法参数解析如下:

  • 从模型对象中检索(如果存在)(通常通过@ModelAttribute带注释的方法添加)
  • 使用@SessionAttributes从HTTP会话中检索。
  • 使用通过转换器与@ModelAttribute名称匹配的URI路径变量创建
  • 使用默认构造函数创建并将其添加到Model

处理程序类可以用@SessionAttributes进行注释,并以名称列表作为其参数。这是为了指示Spring持久保存(在会话中)模型数据中与@SessionAttributes批注中指定的名称匹配的那些数据项。

因此在SampleController中,由于上述解决方法,post方法的@ModelAttribute参数由@SessionAttributes字段解析。

相关问题