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()はセッション全体を無効にするため、そこに保存したログイン情報なども使えなくなります。表示設定だけを消す場面とログアウトを区別します。