org.apache.wicket.Sessionと実際のセッションが自動的に結びつかない場合
org.apache.wicket.Sessionと実際のセッションが自動的に結びつかないケース
下図のアプリについて、2番目のページでは、トップページでセッションに設定した値が取り出せそうですが、実は取り出せません。
理由を端的に言うと、「トップページがステートレスだと判断されるから」です。
ステートレスだと判断されると、どうして「org.apache.wicket.Sessionと実際のセッションが勝手に結びつかないのか」は後述します。
org.apache.wicket.Sessionと実際のセッションを結びつけている箇所
org.apache.wicket.Sessionと実際のセッションはPage.onBeforeRenderで結びつけます。
以下に該当メソッドを抜粋します。
protected void onBeforeRender() { super.onBeforeRender(); // If any of the components on page is not stateless, we need to bind the session // before we start rendering components, as then jsessionid won't be appended // for links rendered before first stateful component if (getSession().isTemporary() && !isPageStateless()) { getSession().bind(); } }
getSession().bind()で実際の結びつけ処理が行われます。
getSession().bind()が実行されるためには上記の引用箇所から分かるように、下記の条件を全て満たす必要があります。
- getSession().isTemporary()がtrueを返す。
- Page.isPageStateless()がfalseを返す。
getSession().isTemporary()は、org.apache.wicket.Sessionと実際のセッションを結びついているときにfalseを返すので、わりとどうでも良いです。要は、getSession().bind()を呼び出しても何も起きない場合にfalseです。
問題は、isPageStateless()です。
今回取り上げた例の場合、トップページ表示時にisPageStateless()がtrueであり、ステートレス扱いされています。
結果、getSession().bind()が行われません。
ステートレスだと判断される条件
下記の全てを満たす場合に、isPageStateless()がtrueを返すため、ステートレスだと判断されます。
- Page.isBookmarkable()がtrueを返す。
- Page.getStatelessHint()がtrueを返す。
- Pageに状態を持つコンポーネントが1個も存在しない。
URLに履歴番号を持つようなコンポーネントは、状態を持ちます。例外があるのかは不明です。
狙わないと、なかなか全ての条件は満たせないかもですね。
Page.isPageStateless()がtrueを返すケースで、org.apache.wicket.Sessionと実際のセッションを結びつけたい場合
二つ方法はあるのですが、どちらが正攻法なのかは私には分かっていません。
- this.setStatelessHint(false)をPageクラスのコンストラクタで呼び出す。
- getSession().bind()をPageクラスのコンストラクタで呼び出す。