I am confused about how to use @SessionAttributes

zono picture zono · Feb 6, 2011 · Viewed 26.9k times · Source

I am trying to understand architecture of Spring MVC. However, I am completely confused by behavior of @SessionAttributes.

Please look at SampleController below , it is handling post method by SuperForm class. In fact, just field of SuperForm class is only binding as I expected.

However, After I put @SessionAttributes in Controller, handling method is binding as SubAForm. Can anybody explain me what happened in this binding.

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

@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>

Answer

axtavt picture axtavt · Feb 6, 2011

When processing POST request, Spring does the following:

  • Without @SessionAttributes: Spring instantiates a new instance of SuperForm (type is inferred from the signature of register()), populates its properties by values from the form fields and passes it to the register() method.

  • With @SessionAttributes: Spring obtains an instance of model attribute from the session (where it was placed when processing GET due to presence of @SessionAttributes), updates its properties by values from the from fields and passes it to the register() method.

That is, with @SessionAttributes , register() gets the same instance of the model attribute object that was placed into the Model by getCreateForm().