【问题标题】:Spring MVC - The @SessionAttributes and status.setComplete()Spring MVC - @SessionAttributes 和 status.setComplete()
【发布时间】:2014-10-16 01:48:39
【问题描述】:

我遇到了一个我真的不知道如何解决的问题。 我正在开发一个错误跟踪器(仅用于学习目的)。我有一个创建新问题的页面和一个编辑问题的页面。目前,两者都有自己的控制器。

EditIssueController.java

@Controller
@RequestMapping(value = "/issues/{issueId}")
@SessionAttributes("issuePackage")
public class EditIssueController {

    @Autowired
    private IssueService issueService;

    [...]

    @ModelAttribute("issuePackage")
    public IssueTagEnvironment populateIssue (@PathVariable("issueId") Integer issueId) {

        IssueTagEnvironment issueTagEnv = new IssueTagEnvironment();
        issueTagEnv.setIssue(issueService.getIssueById(issueId));

        return issueTagEnv;
    }

    @InitBinder
    public void initBinder (WebDataBinder binder) {

        [...]
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView editIssue (@PathVariable("issueId") Integer issueId,
                                   @ModelAttribute("issuePackage") IssueTagEnvironment issuePackage) {

        ModelAndView mav = new ModelAndView("/issues/EditIssue");

        [...]

        IssueTagEnvironment issueTagEnv = new IssueTagEnvironment();
        issueTagEnv.setIssue(issueService.getIssueById(issueId));

        [...]
        mav.addObject("issuePackage", issueTagEnv);

        return mav;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public String updateIssue (@ModelAttribute("issuePackage") IssueTagEnvironment issuePackage,
                               BindingResult result) {

        if (result.hasErrors() == true) {
            return "redirect:/issues/{issueId}/edit";
        }

        issueService.updateIssue(issuePackage.getIssue());

        return "redirect:/issues/{issueId}";
    }
}

CreateIssueController.java

@Controller
@SessionAttributes("issuePackage")
public class CreateIssueController {

    @Autowired
    private IssueService issueService;

    [...]

    @ModelAttribute("issuePackage")
    public IssueTagEnvironment populateNewIssue () {

        return new IssueTagEnvironment();
    }

    @InitBinder
    public void initBinder (WebDataBinder binder) {

        [...]
    }

    @RequestMapping(value = "/issues/CreateIssue", method = RequestMethod.GET)
    public ModelAndView createIssueGet (@ModelAttribute("issuePackage") IssueTagEnvironment issuePackage) {

        ModelAndView mav = new ModelAndView("/issues/CreateIssue");

        [...]

        issuePackage.getIssue().setReporter(SecurityUtils.getCurrentUser());

        return mav;
    }

    @RequestMapping(value = "/issues/CreateIssue", method = RequestMethod.POST)
    public String createIssuePost (@ModelAttribute("issuePackage") IssueTagEnvironment issuePackage,
                                   BindingResult result,
                                   SessionStatus status) {

        if (result.hasErrors() == true) {
            return "redirect:/issues/CreateIssue";
        }

        [...]

        issueService.createIssue(issuePackage.getIssue());

        status.setComplete();
        return "redirect:/issues/" + issuePackage.getIssue().getId();
    }

}

到目前为止,一切似乎都是正确的(并且确实有效)。但这里是龙:

  • 我正在“编辑”页面中更改现有问题的数据。
  • 我决定按导航器中的“返回”按钮,而不是提交更改。
  • 在该操作(返回)之后,我决定创建一个新问题,然后... 就是这样! 创建新问题的表单不是空的,而是填写了上一个“已编辑但未提交”问题的信息。

我了解问题所在:controller 未通过执行 status.setComplete() 完成会话/状态。

我的问题是,如何解决这个问题?

提前感谢社区!

【问题讨论】:

  • 我刚刚找到了这个question/answer,它解释了我的问题,但没有解决它。 :-/

标签: java spring-mvc


【解决方案1】:

对于您当前的示例,很容易修复,只需将 createIssueGet 方法更改为:

public ModelAndView createIssueGet () {

    ModelAndView mav = new ModelAndView("/issues/CreateIssue");
    IssueTagEnvironment issuePackage = new IssueTagEnvironment();

    ModelAndView mav = new ModelAndView("/issues/CreateIssue");
    mav.addAttribute("issuePackage", issuePackage);

    [...]

    [...]
}

这样你就可以确定你总是在那个控制器中使用一个新的IssueTagEnvironment 对象。 Spring 会将其放入会话中,就像您将其放入模型中一样。

但问题仍然存在:如果你没有正确调用status.setComplete(),你会在会话中留下一个应该存在的对象,就像你说的那样龙可能在那里

出于这个原因,我停止使用 @SessionAttributes,只使用隐藏字段(用于 id)和从 id 到使用服务层的完整对象的 Converter,希望它应该在缓存中而不是打数据库。不是很好,但也没有比这更糟。

【讨论】:

  • 我喜欢你的解决方案。太感谢了。虽然我真的不知道如何管理要编辑的问题属性。我的意思是,如何将修改/编辑的问题传递给POST 方法。通过使用Editors?
猜你喜欢
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 2012-05-31
  • 1970-01-01
  • 2011-01-06
  • 1970-01-01
相关资源
最近更新 更多