java - Spring MVC - @SessionAttributes 和 status.setComplete()

标签 java spring-mvc

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

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()来完成 session /状态。

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

预先感谢社区!

最佳答案

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

public ModelAndView createIssueGet () {

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

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

    [...]

    [...]
}

这样您就可以确保在该 Controller 中始终使用新的 IssueTagEnvironment 对象。 Spring 会将其放入 session 中,就像您将其放入模型中一样。

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

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

关于java - Spring MVC - @SessionAttributes 和 status.setComplete(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26387233/

相关文章:

java - 列出序列化数据中的serialVersionUID

java - 是否有等效的 verifyZeroInteractions() 用于验证与模拟对象交互的确切数量?

使用 2 个迭代器的 java.util.ConcurrentModificationException

java - 如果输入不是想要的内容,如何弹出重试窗口?

java - Spring MVC 默认值不起作用

java - 使用 Spring MVC 流媒体的正确方法是什么

spring - 从 Spring Security 中的 Session 获取用户详细信息

Java 企业架构引用

spring - Tiles 2 且未找到带有 URI 的 HTTP 请求的映射 - Spring-MVC

spring - 如何在 Spring 实体类中保留 ArrayList?