JSF2.2入門 第17回CDIとManagedBeanのSessionScoped(セッションスコープ)

17title

CDIとManagedBeanのどちらにも共通するSessionScopedについて解説します。SessionScopedはセッションが有効な期間内に限り有効なビーンです。

katatsumuri-e1463911702620CDIのSessionScoped

leaf-e1463911721194CDIのJavaBeansの書き方

第16回RequestScopedのところで作ったものと同じ趣味を保持するビーンをSessionScopedで作ります。アノーテーションのところがキーポイントです。@NamedはRequestScopedと同じですね。次に@SessionScopedを書きます。それに対応してjavax.enterprise.context.SessionScopedをインポートします。前回RequestScopedのところでは完全修飾子で書いて、その代わりインポート無しとしたわけですが、SessionScopedの場合には、後で説明するようにManagedBeanと同じく@SessionScopedだけで問題なく動きます。やはりCDIにおける@RequestScopedの挙動がちょっとおかしいと思います。執筆時点では。

セッション期間中にビーンは生きていなければいけないので持続可能なように、つまりシリアライズにして保存可能にしなければならないのでSerializableをインプリメントしなければなりません。

[HobbySessionBean.java]

package com.myjsf;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;

@Named(value=”hobbySessionBean”)
@SessionScoped
public class HobbySessionBean implements Serializable{
private String hobby;
public HobbySessionBean() {
}

public String getHobby() {
return hobby;
}

public void setHobby(String hobby) {
this.hobby = hobby;
}

}

leaf-e1463911721194CDIの使い方

前回16回のRequestScopedの時と使い方は同じです。

次のようにJSFページを作ります。趣味を尋ねるh:inputTextタグを1つと様々な動作をチェックするためのh:commandButtonタグを3つ、hobbyプロパティを表示するためのh:outputTextタグが1つあります。

[sessionScopeSample.xhtml]

<?xml version=’1.0′ encoding=’UTF-8′ ?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:h=”http://xmlns.jcp.org/jsf/html”>
<h:head>
<title>SessionScope sample</title>
</h:head>
<h:body>
<h2>SessionScopeの例</h2>
<h:form>
あなたの趣味は何ですか:<h:inputText value=”#{hobbySessionBean.hobby}”/><p/>
<h:commandButton value=”このページで表示” /><p/>
<h:commandButton value=”Forwardして表示” action=”sessionScopeCheckNextPage.xhtml”/><p/>
<h:commandButton value=”Redirectして表示” action=”sessionScopeCheckNextPage.xhtml?faces-redirect=true;”/>
</h:form>
<br/>
あなたが入力した趣味:
<h:outputText value=”#{hobbySessionBean.hobby}”/>
</h:body>
</html>

leaf-e1463911721194実行してみる

まず実行すると次のような画面になりますので、何か入力してみましょう。そして「このページで表示」のボタンを押すとh:outputTextのところにちゃんと表示されます。アドレス欄のところをちょっと見ていただくとわかりますがjsessionid=…….とセッションIDが付与されていますが、これをコピーしてブラウザーの別ウィンドウでペーストしてアクセスするとビーンはそのまま参照できてしまいます。このセッションが有効である限りビーンは生きていて、このセッションIDに結び付けられています。

20161105-2

次のボタン「Forwardして表示」を押しても問題なくビーンは生きていて表示できます。

20161105-3

「さらに次のページへ」ボタンを押して別ページに行っても次のように問題なくビーンは生きています。

20161105-4

入力画面で「Redirectして表示」をやってみても問題なくビーンの内容を表示できます。Redirect先はForward先と同じページを使っています。

20161105-5

セッションのデフォルトの有効期間はアプリケーションのweb.xmlに次のような形で書かれており、この場合30分となっています。

<session-config>
<session-timeout>
30
</session-timeout>
</session-config>

またサーブレットなどプログラム上で次のようにするとセッションを終了することができます。よくあるケースはログアウトしたときにセッション終了するような場合ですね。

ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession) externalContext.getSession(false);
session.invalidate();

または短縮して次のように記述してもいいでしょう。

FacesContext.getCurrentInstance().getExternalContext().invalidateSession();

katatsumuri-e1463911702620ManagedBeanのSessionScoped

今度はManagedBeanの場合について解説します。ビーンのアノーテーションなど定義のしかたが違うだけで使い方はCDIと全く同じです。使い方の説明は省略します。

leaf-e1463911721194ManagedBeanのSessionScopedの書き方

CDIの場合と違う点は赤い文字のところです。@SessionScopedは同じなんですが、それが定義されているパッケージが違って javax.faces.bean.SessionScopedです。それをインポートします。

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class HobbySessionBeanMB implements Serializable{
private String hobby;
public HobbySessionBeanMB() {
}

public String getHobby() {
return hobby;
}

public void setHobby(String hobby) {
this.hobby = hobby;
}
}

動作確認を1つだけ掲載しておきます。

20161105mb-1

 

previousnext

JSF2.2のすべてをまとめたkindle電子書籍 「JavaServer Faces2.2 入門」もぜひご覧ください。パソコン、iPhone、Androidどんな端末用にもamazonが無料のKindle電子書籍リーダーを用意しています。それをつかってKindle本を手軽にお楽しみください。あなたが今お使いの端末用Kidle電子書籍リーダーのご案内