spring mvc 3 - SessionAttributes 似乎不起作用

发布于 2024-11-30 22:51:57 字数 1183 浏览 0 评论 0原文

我已经尝试过,但无法弄清楚这里发生了什么。

  1. 我有一个使用 @Controller 注释的简单控制器
  2. 我也有 @SessionAttributes 注释
  3. 我处理 GET 请求并将一个对象放入模型中。
  4. 当我从表单中返回 POST 时,我只返回用户填充的内容。我不会取回完整的对象。

我对 SessionAttributes 很陌生,但我认为这保留了整个对象,并且当使用 @ModelAttribute 在方法中读回该对象时,它将合并该对象(即表单更改的对象)。但是,我没有看到这种行为。

任何帮助将不胜感激。

以下是代码中的相关部分:

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

您看到我可能错过的任何内容吗?我花了将近一天的时间试图弄清楚这一点,但就是做不到。任何帮助将不胜感激。

更新:我弄清楚了问题所在。答案发布在下面。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别挽留 2024-12-07 22:51:57

经过一番努力我才明白发生了什么。我希望这可以节省其他人的时间。

这里的根本问题是双重的:

  1. 保存在会话中的对象被一些aspectj符号修饰。因此,对象的属性值仅由适当的 get 访问器返回。
  2. 我已经进行了休眠验证(请注意处理 POST 的方法中的 @Valid 注释)。验证器注释直接位于每个字段上(如下所示):

    @NotNull
    私有字符串名称;

这是我修复它的方法。

  1. 仅出于测试目的,我删除了 @Valid 并注意到即使字段本身似乎为 NULL,我们仍将正确的数据保存在后端存储中。这就是让我了解这个问题的根本原因的原因。
  2. 我认为验证器注释是导致我将验证器注释移动到获取方法的原因。于是代码改成如下:

    私有字符串名称;

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

  3. 我放回 @Valid 注释并验证验证不再失败。

希望它可以帮助那里的人并节省他们一天的工作。 :)

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. :)

貪欢 2024-12-07 22:51:57

我不希望 spring 合并 form session 和 form 的属性。您应该将表单提交的用户和会话中的用户分开。

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.

唐婉 2024-12-07 22:51:57

我和 Azeem 有同样的问题,并且由于他没有明确确认 sessionattribute 可用于“合并”原始表单支持对象与提交中发布的更改,所以我想指出,是的,表单的更改提交确实会合并到原始表单支持对象中。

中指出的那样,这种方法可能存在一些问题

正如Spring MVC 3.0:如何绑定到持久对象

但是当您有一个复杂的表单支持对象但只允许用户更新一些对象图成员时,这种方法非常有用在形式上而不是在形式上使用隐藏字段来维护表单元素中复杂对象的其余部分。

当使用此方法而不在类上使用 @SessionAttributes("xxx") 注释时,返回的表单支持对象基本上为 null,除了表单专门提交的那些成员之外。这会使持久更新的对象变得非常困难,因为您必须自己将新的更新组合到原始对象中。但通过使用会话属性,提交后提供的完整更新的表单支持对象使得持久化对象图变得更加容易。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文