开发者

spring mvc 3 - SessionAttributes doesn't seem to be working

开发者 https://www.devze.com 2023-03-29 20:13 出处:网络
I have tried and tried but can\'t figure out what is going on here. I have a simple controller annotated using @Controller

I have tried and tried but can't figure out what is going on here.

  1. I have a simple controller annotated using @Controller
  2. I also have annotation for @SessionAttributes
  3. I handle a GET req开发者_Go百科uest and put an object into the model.
  4. When I get back the POST from the form, I only get back what the user has populated. I'm not getting back the complete object.

I'm new to SessionAttributes but I thought this preserved the whole object and when the object was read back in the method using @ModelAttribute, it would be merged the object (i.e. the object that the form changed). However, I'm not seeing this behavior.

Any help would be much appreciated.

Here is the relevant pieces from the code:

@Controller
@RequestMapping("/user")
@SessionAttributes("user")
public class UserController 
{
      // ... 

@RequestMapping(value = "/{login}", method = RequestMethod.GET)
public String profile(Model model, @PathVariable("login") String login)
      {
           // ...
           model.addAttribute("user", user); 
           // ...
      }

@RequestMapping(value="/{login}", method = RequestMethod.POST)
public String saveProfile(@ModelAttribute("user") @Valid User user, BindingResult result, SessionStatus status)
{
     if (result.hasErrors())
           {
           return "user/index";
     }
           // ... 
           status.setComplete();
     return "redirect:/user/"+user.getLogin(); 
}

Do you see anything that I may have missed? I have spent almost a day trying to figure this out and just can't. Any help would be much appreciated.

Update: I figured out what the issue was. Answer posted below.


I figured out what was going after much laboring. I hope this saves somebody else the time.

The underlying problem here was twofold:

  1. The object being saved in the session was decorated with some aspectj notations. Because of this the attribute values for the object were only returned by the appropriate get accessors.
  2. I had hibernate validation in place (note the @Valid annotation in the method that handles the POST). The validator annotations were directly on each field (as below):

    @NotNull private String name;

Here is how I fixed it.

  1. For testing purposes only, I removed the @Valid and noticed that even though the fields themselves seem to be NULL, we were saving the correct data in our backend store. This is what clued me into the root cause of this issue.
  2. I figured the validator annotations were causinI moved the validator notation to get methods. So the code changed as follows:

    private String name;

    @NotNull public String getName() {...}

  3. I put the @Valid annotation back in and verified that the validation was no longer failing.

Hope it helps someone out there and save them a day of work. :)


I would not expect that spring merges the properties form session and form. You should separate the user that is submitted by the form, and the user from the session.


I had the same question as Azeem, and since he did not explicitly confirm that sessionattribute can be used to "merge" the original form backing object with the changes posted in the submit, I wanted to point out that yes, the changes from the form submit do get merged into the original form backing object.

There can be some issues with this approach as pointed out in

Spring MVC 3.0: How do I bind to a persistent object

but this approach is very helpful when you have a complex form backing object but you are only allowing the user to update a few of the object graph members in the form and not using hidden fields to maintain the remainder of the complex object in form elements.

When this approach is used without the use of the @SessionAttributes("xxx") annotation on the class, the returned form backing object is basically null except for those members specifically submitted by the form. This can make persisting the updated objects very difficult because you would have to combine the new updates into the original object yourself. But with use of the sessionattribute, the full updated form backing object provided after the submital makes persisting the object graph much easier.

0

精彩评论

暂无评论...
验证码 换一张
取 消