Spring :@SessionAttributes与HttpSession

标签 spring spring-mvc

@SessionAttributes和HttpSession有什么区别?
两者中的哪一个会在 session 中保留更多时间?
在哪些情况下我必须使用一种?在哪些情况下我必须使用另一种?

谢谢

最佳答案

@SessionAttributes允许在请求之间持久化模型属性 session ,并且应根据具体情况来确定。目的是要提供一种构造,该构造将朝着实现对话范围(比 session 短,比请求长)迈出一步。在blog中很好地解释了对话范围的需求以及为什么@SessionAttributes无法完全使用对话范围。

它可以自动存储匹配的模型属性(匹配基于名称)。默认存储为HttpSession,但是也可以使用其他方式进行配置。医生说

Session attributes as indicated using this annotation correspond to a specific handler's model attributes, getting transparently stored in a conversational session. Those attributes will be removed once the handler indicates completion of its conversational session.



但是,一旦处理程序指示其 session session 完成,这些属性将被删除。不会自动发生,而是由开发人员通过在SessionStatus实例上使用setComplete指示退出对话。否则,models属性将保留在 session 中,这通常是不希望的副作用。

理解差异的最简单方法是观察模型变量,以@SessionAttribute为后盾的模型变量和“正常” HttpSession变量的范围和值。

看一下两个简单的 Controller
@Controller
@SessionAttributes("modelAndSession")
@RequestMapping("/sessionattr")
public class FirstController {
    protected static final String NEXT_VIEW = "next";
    @RequestMapping("/init")
    public String handlingMethod1( Model model, HttpSession session) {
        model.addAttribute(NEXT_VIEW, "/sessionattr/afterinit");
        session.setAttribute("session", "TRUE");
        model.addAttribute("modelAndSession", "TRUE");
        model.addAttribute("model", "TRUE");
        return "index";
    }

    @RequestMapping("/afterinit")
    public String handlingMethod2(SessionStatus status, Model model) {
        model.addAttribute(NEXT_VIEW, "/nosessionattr/init");
        //status.setComplete();
        return "index";
    }

}

第二个 Controller
@Controller
@RequestMapping("/nosessionattr")
public class SecondController {
    protected static final String NEXT_VIEW = "next";
    @RequestMapping("/init")
    public String handlingMethod3(Model model) {
        model.addAttribute(NEXT_VIEW, "/sessionattr/init");
        return "index";
    }
}

和将触发流程的 View
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<a href="${next}">Next step ${next}</a>
<hr/>
<table>
     <thead>
          <th>key</th> <th>Request scope</th> <th>Session scope</th>
     </thead>
    <tr>
        <td>model</td> <td>${requestScope.model}</td> <td>${sessionScope.model}</td>
    </tr>
    <tr>
        <td>model and session</td> <td>${requestScope.modelAndSession}</td> <td>${sessionScope.modelAndSession}</td>
    </tr>
    <tr>
        <td>session</td> <td>${requestScope.session}</td> <td>${sessionScope.session}</td>
    </tr>
</table>



在初始请求/sessionattr/init时, View 呈现如下

因此,模型变量可在请求范围内使用,sessionattribute在请求和 session 范围内均可使用,“正常” session 属性仅在 session 范围内可用

在下一个请求/sessionattr/afterinit上, View 呈现如下

因此,仅用于模型的变量消失了,而@SessionAttribute模型属性从 session 推到模型中并在请求中持久存在。下一步将针对第二个 Controller /nosessionattr/init,该 View 将如下所示

现在@SessionAttribute模型对象已从模型中删除,但是由于未显式调用status.setComplete,因此将其作为常规变量保留在 session 中

这是一个特别令人困惑的场景,因为许多人期望@SessionAttribute模型对象在切换处理程序后应该消失,但是除非明确清除它,否则它将保留在 session 中。随意复制代码片段,并进一步调查使您感到困惑的组合

关于 Spring :@SessionAttributes与HttpSession,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27191798/

相关文章:

java - Spring MVC : issue between xml and annotation configurations

java - 在 Spring dataSource 上获取空指针

java - 如何以编程方式将已设置的 bean 注册到 spring 上下文

使用扩展 DefaultBatchConfiguration 的编程方式时未创建 Spring Batch 5 和 Spring Boot 3 元数据表

java - Spring Boot 测试 - 如何在 Spring Boot 之前启动嵌入式服务器?

unit-testing - 我必须为 SpringMVC3.2 单元测试导入什么?

java - 访问受 OAuth 安全保护的 Rest 服务的最佳方式是什么?

java - 可以通过单击 <spring :message>? 提交隐藏输入

java - 在使用 JPA 在 Spring 中保持多对一关系的同时,它添加了额外的不必要的父实体

Spring 与 Thymeleaf View 集成