关于控制器退出后是否清除会话属性存在很大的争议。
为了一劳永逸地澄清,我们可以查看Spring MVC 3.1.0 RELEASE源代码。
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对象来存储属性,因此它们可能会被同一会话中的其他控制器访问。
所以不,在干净的 POST 之后不会删除会话属性。