gpt4 book ai didi

spring - 如果我忘记将 Spring SessionStatus 标记为 "Complete"会发生什么?

转载 作者:IT老高 更新时间:2023-10-28 13:51:52 27 4
gpt4 key购买 nike

在 Spring MVC 中,假设我使用 @SessionAttribute 标签定义了一个 SessionAttribute,如下所示:

@SessionAttributes(value = "myModel")
public class MyController{
...
}

假设我忘记像这样在 SessionStatus 上调用 status.setComplete():

@RequestMapping(method = RequestMethod.POST)
public void doSomething(@ModelAttribute("myModel") MyModel model, SessionStatus status){
...
//status.setComplete(); <-- Never gets called
}

模型会永远留在 session 中吗?它会被清理掉,还是会随着用户浏览网站而变得越来越大?

最佳答案

关于 Controller 退出后是否清除 session 属性存在很大的争议。

为了一劳永逸,我们可以看一下Spring MVC 3.1.0 RELEASE源代码。

接口(interface)org.springframework.web.bind.support.SessionAttributeStore公开了以下方法:

void storeAttribute(WebRequest request, String attributeName, Object attributeValue);

Object retrieveAttribute(WebRequest request, String attributeName);

void cleanupAttribute(WebRequest request, String attributeName);

默认实现是org.springframework.web.bind.support.DefaultSessionAttributeStore

通过在 Eclipse 中对 cleanupAttribute() 执行“Open Call Hierarchy”,我们可以看到该方法被 2 个不同的流程调用:

1) org.springframework.web.method.annotation.ModelFactory

public void updateModel(NativeWebRequest request, ModelAndViewContainer mavContainer) throws Exception {

if (mavContainer.getSessionStatus().isComplete()){
this.sessionAttributesHandler.cleanupAttributes(request);
}
else {
this.sessionAttributesHandler.storeAttributes(request, mavContainer.getModel());
}

if (!mavContainer.isRequestHandled()) {
updateBindingResult(request, mavContainer.getModel());
}
}

2) org.springframework.web.bind.annotation.support.HandlerMethodInvoker

public final void updateModelAttributes(Object handler, Map<String, Object> mavModel,
ExtendedModelMap implicitModel, NativeWebRequest webRequest) throws Exception {

if (this.methodResolver.hasSessionAttributes() && this.sessionStatus.isComplete()) {
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
this.sessionAttributeStore.cleanupAttribute(webRequest, attrName);
}
}
...
}

很明显,在这两种情况下,只有在调用 this.sessionStatus.isComplete() 时才会移除 session 属性。

我研究了DefaultSessionAttributeStore的代码。在底层,它获取真正的 HTTP Session 对象来存储属性,因此它们可能会被同一 session 中的其他 Controller 访问。

所以不,在干净的 POST 之后不会删除 session 属性。

关于spring - 如果我忘记将 Spring SessionStatus 标记为 "Complete"会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/880746/

27 4 0