简体   繁体   English

Spring MVC 3-SessionAttributes似乎不起作用

[英]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 我有一个使用@Controller注释的简单控制器
  2. I also have annotation for @SessionAttributes 我也有@SessionAttributes的注释
  3. I handle a GET request and put an object into the model. 我处理GET请求,然后将对象放入模型。
  4. When I get back the POST from the form, I only get back what the user has populated. 从表单取回POST时,我仅取回用户已填充的内容。 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). 我是SessionAttributes的新手,但我认为这可以保留整个对象,并且当使用@ModelAttribute在方法中读回该对象时,它将合并该对象(即,表单更改的对象)。 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. 会话中保存的对象已用一些aspectj标记修饰。 Because of this the attribute values for the object were only returned by the appropriate get accessors. 因此,对象的属性值仅由适当的get访问器返回。
  2. I had hibernate validation in place (note the @Valid annotation in the method that handles the POST). 我已经设置了休眠验证(请注意处理POST的方法中的@Valid注释)。 The validator annotations were directly on each field (as below): 验证者注释直接位于每个字段上(如下所示):

    @NotNull private String name; @NotNull私有字符串名称;

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. 仅出于测试目的,我删除了@Valid并注意到,即使字段本身看起来为NULL,我们仍将正确的数据保存在后端存储中。 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() {...} @NotNull公共字符串getName(){...}

  3. I put the @Valid annotation back in and verified that the validation was no longer failing. 我放回@Valid批注,并验证验证不再失败。

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. 我和Azeem有相同的问题,因为他没有明确确认sessionattribute可用于“合并”原始表单支持对象和提交中的更改,所以我想指出的是,是对表单的更改提交合并到原始表单支持对象中。

There can be some issues with this approach as pointed out in 如该方法中指出的那样,可能存在一些问题

Spring MVC 3.0: How do I bind to a persistent object Spring MVC 3.0:如何绑定到持久对象

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. 当在类上不使用@SessionAttributes(“ xxx”)注释的情况下使用此方法时,返回的表单支持对象基本上为null,但由表单专门提交的成员除外。 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. 但是,通过使用sessionattribute,提交后提供的完整更新的表单支持对象使持久化对象图变得更加容易。

I would not expect that spring merges the properties form session and form. 我不希望spring将属性表单会话和表单合并。 You should separate the user that is submitted by the form, and the user from the session. 您应该将表单提交的用户以及该用户与会话分开。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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