この問題を再現できるコードは次のとおりです。
@Controller
public class FirstController {
@RequestMapping(value = "firstpage", method = GET)
public String myHander(HttpSession httpSession) {
if (httpSession.getAttribute("someClass") == null) {
httpSession.setAttribute("someClass", new SomeClass());
}
return "firstpage";
}
}
最初のコントローラーは、まだセッションにない場合は、何かをセッションに配置します。
@Controller
@SessionAttributes(types = SomeClass.class)
public class SecondController {
@RequestMapping(value = "secondpage", method = GET)
public String myHandler(SomeClass someClass, HttpSession httpSession) {
//asking spring for the SomeClass parameter, that's why we put it in the annotation.
System.out.print(someClass.hashCode());
httpSession.invalidate();
return "secondpage";
}
}
2 番目のコントローラーがセッションを強制終了します。
両方のjspファイルに、セッションオブジェクトのハッシュコードとセッション属性のハッシュコードを出力する次のコードがあります。
session hash:
<%= session.hashCode() %>
<br/>
someclass hash:
<%= session.getAttribute("someClass").hashCode() %>
アプリケーションを実行して「firstpage」にアクセスすると、次のようになります。
セッション ハッシュ: 1838367636
someclass ハッシュ: 1075505853
次に、「secondpage」にアクセスすると、次のようになります。
セッション ハッシュ: 842656294
someclass ハッシュ: 1075505853
2 番目のコントローラーがセッションを強制終了するため、セッション自体が変更されていることがわかります。ただし、(タイプ SomeClass の) セッション属性は同じままです。
次に、「secondpage」に再度アクセスしようとすると、セッション オブジェクトは毎回変更されますが、セッション属性は同じままです。
セッション属性 (セッションにアタッチされることになっている) のライフサイクルがセッション自体よりも長いのはなぜですか?
PS: 完全なコードはこちら: https://github.com/cuipengfei/One-hundred-thousand-why/tree/master/20130701SessionAttributesLifeCycle/SpringMVC
mvn jetty:run で実行して、問題を再現できます。