はじめに
JavaでつくるWebページについて学んできていますが、ページが1ページだけで終わるという事はなかなかないですよね。
たくさんの情報を載せたいのでWebページは複数にわたります。
複数あるページを扱う時、ページが切り替わるたびにログインIDや入力情報を求められたら大変ですね。
今回はページをまたいでも入力情報を保持しておける仕組みを学んでいきます。
Step1: 概念を知る
Webスコープ
サーブレットやJSPをまたいでデータを共有したい場合に用いる保存領域のこと。
共有範囲に応じて以下の3種類がある。
どうでしょうか?
Webスコープの種類と機能はなんとなく理解できたけど、まだフワッとしていて落とし込めない方が多いかと思います。
そこで、理解の助けになる例を一つあげます。
【入館証: セッション】
本日は20XX年3月14日。
みなさんは就活中だとしましょう。
企業がたくさん入っている10階建てのビルに向かったとします。
今回みなさんが受ける企業は7階にあって、16時から面接です。
ビルに入ったら受付で必要事項を記入した後、問題無ければ入館証を渡されます。
ビル内の企業のフロアは入館証が無いとドアが開かない仕様となっていて、ドアの先にお客様用の受付電話があるとしましょう。
本日はビルの点検工事の都合で19時にはすべての企業が完全撤退を強いられるため、入館証の有効期限は18時までのようです。
入館証が有効な間は企業の入り口までは入れますが、期限切れで無効になってしまった場合は、 再度受付で発行してもらわないといけません。
… といったところで解説!
・セッションの開始と終了
上記例の場合、
セッションの開始 (=入館証を渡されたタイミング)
セッションの終了(=期限切れで無効のタイミング)
となります。
・セッション切れ
セッション(=入館証の有効期限) としています。
有効期限が過ぎた入館証で企業へのアクセス (ピッって入館証を読み取り機器にあてる) する行為は無効で、おそらくその入館証無効だよ! 的なエラー音などが発せられるかもしれません。
(このエラーがいわゆる 「セッションタイムアウト」 ってやつです! )
・セッションの持つ情報
上記例の場合は、 (面接を受けに行った) 自分自身が情報です。
入館証が有効な間は自分という情報をビル内部で扱うこと (ビル内の移動や、企業入り口への入場) ができます。
先程の種類と機能の内容を読んだときよりも、Webスコープ (特にセッション) についての理解は深まったのではないでしょうか?
このイメージを持って以降の内容を読み進めてみましょう!
Step2: 使い方を知る
下記にWebスコープのセッションを使用した属性を設定する例を示します。
各Webスコープに属性を設定します。
属性はWebスコープの有効範囲内で維持され、必要に応じて設定した属性の値を取得することが可能です。
各Webスコープを表すクラスを設定します。
クラスそれぞれに用意されている、setAttribute() メソッドとgetAttribute() メソッドを用いて属性の設定や取得を行います。
セッションは、HttpServletRequestクラスのオブジェクトの request から getSession() メソッドで生成します。
そのセッションの setAttribute() メソッドで第1引数に属性の名前を文字列で与え、第2引数で属性値を与えます。
これで属性の設定となります。
上記の例では、属性値に JobSupport という文字列を与えていますが、属性値はJavaのオブジェクトであれば何でも与えられます。
例えば、 自作のクラスをオブジェクトにして属性値して与えることも可能です。
別のサーブレットにてセッションに設定した属性値を取得したい場合は、下記のようになります。
属性を設定する時と同様に、 セッションを生成します。
そのセッションから属性値を取得するには getAttribute()メソッドで引数に属性の名前を文字列で与えることで、対応する属性値が取得できます。
ポイント
getAttribute () メソッド使用時の注意点ですが、getAttribute() メソッドの戻り値の型は Object型となります。
そのため、 特定のクラスの型に代入するにはキャストする必要があります。
・キャスト
元の変数の型はそのままで、一時的に宣言時とは別の型に置き換えること。
session.getAttribute("NAME"); の際に必要になり、ここでは String にキャストしています。
取得する値の型と、 キャストする値の型が不一致の場合は、 ClassCastException という例外が発生しますのでsetAttribute() で格納した値の型と必ず一致するようにキャストしましょう!
例外処理を施したり、instanceof という変数の型をチェックする演算子を用いてキャスト時の対応を行ったりしてもよいのですが、 プログラム中の値の取り扱いや運用後の保守性を鑑みると基本的には同一のキー名で、複数の型を格納するなんてことは避けるべきですので、 「setAttribute() を用いて格納する 値型・キー名は一意となるよう開発以前の仕様として定めておく」ようにしましょう。
