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

谢谢

最佳答案

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

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



但是,一旦处理程序指示其 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/

10-10 23:20