简体   繁体   中英

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

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 request 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 (ie 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 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM