Javaのスコープとは?ページ・リクエスト・セッション・アプリケーションの違い|確認問題の回答例

Javaのスコープとは?ページ・リクエスト・セッション・アプリケーションの違いの確認問題の回答例です。使える範囲と保存する期間を分けて考えましょう。

問題1:4種類のデータを、それぞれの範囲へ保存する

商品一覧のJSPだけで使う見出し、今回の検索結果、画面を移動しても使う表示設定、全員共通のサイト名を保存します。属性として扱うなら、それぞれどのスコープが合いますか。

データ回答例
今回のJSP内の見出しページスコープ。pageContextの属性として使える。単純な表示ならローカル変数でもよい。
今回の検索結果リクエストスコープ。Servletからforward先のJSPへ渡す。
画面を移動しても使う表示設定セッションスコープ。同じセッションの複数リクエストで使う。
全員共通のサイト名アプリケーションスコープ。同じWebアプリのServletContextで共有する。

問題2:forwardは3件、redirectはデータなし

requestにresultCountとして3を保存しました。同じresult.jspへforwardする場合とredirectする場合で、記事のJSPにはそれぞれ何が表示されますか。

forwardなら「検索結果:3件」です。同じrequestのresultCountを取り出せます。redirectなら、ブラウザが送る新しいrequestにresultCountがないため、「検索結果が渡されていません。」です。nullを0件と読み替えてはいけません。

問題3:ページではなくrequestから取得する

Servletでrequest.setAttribute("heading", "商品一覧")を実行してJSPへforwardしました。JSPのpageContext.getAttribute("heading")では取得できませんでした。なぜですか。どう直しますか。

保存先はrequestですが、引数が名前だけのpageContext.getAttributeはページスコープだけを探しているためです。属性名が同じでも保存先は別です。JSPでは次のように取得します。

String heading = (String) request.getAttribute("heading");

問題4:利用者IDを全員共通の場所に置かない

AさんとBさんのログイン情報をgetServletContext().setAttribute("loginUserId", 値)で保存しています。Bさんのログイン後、何が起きる危険がありますか。保存先はどう分けますか。

同じServletContextの同じ名前を上書きするため、Aさんの次の処理でBさんの利用者IDを読んでしまう危険があります。本人確認に成功した利用者情報は、そのアクセスに対応するセッションへ保存し、同じアプリだからという理由で全員共通にはしません。

アプリケーションスコープにはサイト名などの共通情報を置きます。セッションに保存しただけで認証が成立するのではなく、本人確認に成功した情報を保存することが前提です。

問題5:同じセッションなら別タブでも設定を共有する

同じセッションを共有する別タブで、一方からdisplayModeを変更しました。もう一方には影響しますか。また、session.removeAttribute("displayMode")とsession.invalidate()はどう違いますか。

同じセッションなので、もう一方のタブも次のリクエストで変更後のdisplayModeを読み取ります。既に表示済みの画面が、それだけで自動的に書き換わるわけではありません。

removeAttribute(“displayMode”)は、その名前の属性だけを削除します。他の属性やセッション自体は残ります。invalidate()はセッション全体を無効にするため、そこに保存したログイン情報なども使えなくなります。表示設定だけを消す場面とログアウトを区別します。

元の記事に戻る

Javaのスコープとは?ページ・リクエスト・セッション・アプリケーションの違い