English 中文(简体)
我对如何使用@SessionAttributes感到困惑
原标题:I am confused about how to use @SessionAttributes

我试图理解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>
最佳回答

当处理<code>POST</code>请求时,Spring会执行以下操作:

  • 如果没有@SessionAttributes:Spring实例化SuperForm的一个新实例(类型是从register()的签名推断出来的),用表单字段中的值填充其属性,并将其传递给register()方法。

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

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

问题回答

再加上@axtavt所说的:假设在<code>getCreateForm</code>中,您正在为下拉列表(列表或映射)放置一些值,或者您正在将一些值以您想要的形式放置在register方法中,但您不希望它们以形式显示(甚至不希望显示在隐藏字段中)。现在假设register方法中发生错误,您需要再次显示表单。要填充下拉值和下一篇文章中需要的其他值,您必须以表单形式重新填充它们。@SessionAttribute在这里有帮助,正如上面很好地描述的@axtavt一样。

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

}

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

  • Retrieve from model object if it is present (normally added via @ModelAttribute annotated methods)
  • Retrieve from HTTP session by using @SessionAttributes.
  • Create using URI path variable that matches the @ModelAttribute name through a converter
  • Create using default constructor and add it to Model.

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

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





相关问题
array dependency injection in spring?

is there a way to use dependency injection to inject all available implementations of a specific interface in spring? This is kind of the same thing as asked here for .NET. Though my aim is to use @...

Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Grails Packaging and Naming Conventions

Packaging Controllers, Services,etc. i.e. - com.company.controllers - com.company.services Is this a good practice or should be avoided by all means?? Another worth mentioning problem I encountered ...

How can I determine Objects in application context?

I am trying to write a portlet for Liferay (using Tomcat and Spring) and need to use a database via Persistence API/Hibernate. I am using some configuration XMLs (applicationContext.xml, etc.) and ...

How to prevent JPA from rolling back transaction?

Methods invoked: 1. Struts Action 2. Service class method (annotated by @Transactional) 3. Xfire webservice call Everything including struts (DelegatingActionProxy) and transactions is configured ...

热门标签