JSP(JavaServer Pages)は、一見すると通常のHTMLドキュメントのように見えますが、内部にJavaコードを埋め込んだり、特殊なタグ(EL式やJSTLなど)を使用したりできるため、強力な動的Web開発技術として機能します。これにより、HttpServletRequestやHttpServletResponseといったサーブレットAPIのオブジェクトにアクセスし、クライアントとのリクエスト・レスポンス処理を制御できます。
JSPの動作メカニズムとして、初回アクセス時にWebコンテナ(Tomcatなど)によってサーブレットクラス(.java)に変換され、コンパイルされてから実行されます。この生成されたサーブレットのソースコードは、Tomcatの場合はworkディレクトリ内で確認可能です。
JSPの主要ディレクティブ
JSPページの構成を制御するために、主に以下の3つのディレクティブが使用されます。
- page: ページ全体の設定(エンコーディングやインポートなど)を定義します。
- include: 他のJSPファイルや静的リソースをページに取り込みます。
- taglib: カスタムタグライブラリ(JSTLなど)を利用するために宣言します。
暗黙オブジェクト(Implicit Objects)
JSPでは、宣言しなくてもスクリプトレット内で利用可能な9つの特殊なオブジェクトが用意されています。
| オブジェクト名 | クラス/型 | 役割 |
|---|---|---|
| out | javax.servlet.jsp.JspWriter | クライアントへの出力ストリーム |
| request | javax.servlet.http.HttpServletRequest | クライアントからのリクエスト情報 |
| response | javax.servlet.http.HttpServletResponse | クライアントへのレスポンス情報 |
| config | javax.servlet.ServletConfig | サーブレットの初期化パラメータ |
| session | javax.servlet.http.HttpSession | ユーザーセッション情報の保持 |
| application | javax.servlet.ServletContext | アプリケーション全体での共有データ |
| page | java.lang.Object | 現在のサーブレットインスタンス(thisに相当) |
| pageContext | javax.servlet.jsp.PageContext | ページのコンテキストとスコープ管理 |
| exception | java.lang.Throwable | エラーページでの例外情報 |
スコープの種類
データを保存する範囲(スコープ)は以下の4つに分類されます。
- pageScope: 現在のJSPページ内のみ有効。
- requestScope: 同一リクエスト内(フォワード先含む)で有効。
- sessionScope: ユーザーのセッションが維持されている間有効。
- applicationScope: アプリケーションが起動している間、全ユーザーで共有。
PageContextによるスコープ操作
PageContextは、単なるページスコープの管理だけでなく、他のスコープに対するデータ操作も一元的に行うためのメソッドを提供します。
setAttribute(String key, Object val): ページスコープに保存。setAttribute(String key, Object val, int scope): 指定したスコープに保存(例:PageContext.REQUEST_SCOPE)。findAttribute(String key): ページ、リクエスト、セッション、アプリケーションの順で属性を検索し、最初に見つかった値を返します。
以下のコード例では、同名のキーで異なるスコープに値を格納し、findAttributeの動作を確認しています。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>スコープテスト</title>
</head>
<body>
<%
// ページスコープに設定
pageContext.setAttribute("user_id", "Alice");
// リクエストスコープに設定
pageContext.setAttribute("user_id", "Bob", PageContext.REQUEST_SCOPE);
// セッションスコープに設定
pageContext.setAttribute("user_id", "Charlie", PageContext.SESSION_SCOPE);
// アプリケーションスコープに設定
pageContext.setAttribute("user_id", "Dave", PageContext.APPLICATION_SCOPE);
%>
<!-- findAttributeは一番小さいスコープから探す -->
<%= pageContext.findAttribute("user_id") %>
</body>
</html>
この例では、findAttribute("user_id")は最も優先度の高いページスコープから"Alice"を見つけるため、結果として「Alice」のみが出力されます。スコープの検索順序を理解するため、キー名は被らせないように設計するか、明示的にスコープを指定して取得することが推奨されます。