動的なウェブページを構築するためのJavaテクノロジーである JSP(Java Server Pages) の基本について学びました。JSPの核心概念である内蔵オブジェクトのスコープから、各種タグ、そしてデータのやり取りまでをソースコードと一緒に整理します。
1. JSP 内蔵オブジェクトと4大領域(Scope)
JSPには、開発者が直接オブジェクトを生成しなくても、サーバーが自動的に提供してくれる「内蔵オブジェクト」が存在します。これらのオブジェクトは、データを保持できる有効範囲(スコープ)によって以下の4つに分類されます。


pageContext ➔ request ➔ session ➔ application
- pageContext(page領域)
現在のページのみ: 単一のJSPページ内でのみデータが維持されます。ページを外れるとデータは消滅します。 - request(request領域)
リクエストの生存期間(通信のやり取り): クライアントがリクエスト(送信)を送ってから、サーバーがレスポンス(応答)を返すまで維持されます。フォワード(Forward)を使用することで、一度にデータをまとめて別のページへ引き継ぐことができます。 - session(session領域)
ブラウザの生存期間: サーバーが起動しており、ウェブブラウザが開いてから閉じられるまでデータが維持されます。主にログイン状態の維持やカート機能に使用されます。 - application(application領域)
アプリケーション全体(サーバー全体): トムキャット(WAS)などのサーバーが起動してから停止するまで、すべてのユーザーが共通でデータを共有できる最も巨大な領域です。
2. JSPのスクリプト要素(Scripting Tags)
JSPファイル内でJavaコードを記述するための3つの基本的なタグ(文法)です。
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jspTag</title>
</head>
<body>
<%-- Declaration(宣言文) : メンバ変数やメソッドの定義 --%>
<%!
public int add(int x, int y){
return x + y;
}
%>
<%-- Scriptlet(スクリプトレット) : 通常のJavaコード(ローカル変数・ロジック) --%>
<%
// 地域 変数 宣言
int result = add(20, 30);
// JSPから出力する方法
// 1) サーバーコンソールへのログ出力
System.out.println("result = " + result);
// 2) JspWriter オブジェクトを使用して応答(response)として出力
out.write("<p>result = " + result + "</p>\r\n");
// 3) Expression(表現式)の使用
%>
<%-- Expression(表現式) : 変数やリターン値を画面に直接出力(セミコロンは不要) --%>
<p>結果 = <%=result %></p>
<%
Date date = new Date();
%>
<p><%=date %></p>
</body>
</html>
3. 制御文の活用(条件文と繰り返し文)
JSPのスクリプトレットタグを分割することで、HTMLのタグの間にJavaの条件文(if)や繰り返し文(for)を埋め込むことができます。
① 条件文の実装例 (condition.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>condition</title>
</head>
<body>
<%
int day = 1;
%>
<%
if(day == 1 || day == 7){
%>
<p>今日は週末です。</p>
<%
} else {
%>
<p>今日は平日です。</p>
<%
}
%>
</body>
</html>
② 繰り返し文の実装例 1:ArrayListの出力
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<%
ArrayList<String> list = new ArrayList<>();
list.add("ドゥーリー");
list.add("ドウナー");
list.add("コ・ギルドン");
list.add("トッチ");
%>
<ul>
<% for(String x : list) { %>
<li><%=x %></li>
<% } %>
</ul>
</body>
</html>
③ 繰り返し文の実装例 2:テーブル(HTML Table)への出力 (loop.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>loop</title>
<style>
table {
font-family : arial, sans-serif;
border-collapse : collapse;
width : 100%;
}
td, th {
border : 1px solid #dddddd;
text-align : left;
padding : 8px;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>名前</th>
<th>電話番号</th>
<th>メールアドレス</th>
</tr>
</thead>
<tbody>
<% for(int i = 0; i < 2; i++) { %>
<tr>
<td>test<%=i + 1 %></td>
<td>010-1111-222<%=1 + 1 %></td>
<td>test<%=i+1 %>@test.com</td>
</tr>
<% } %>
</tbody>
</table>
</body>
</html>
④ 変数と書式(DecimalFormat)の活用 (variable.jsp)
<%@page import="java.text.DecimalFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>variable</title>
</head>
<body>
<%
int inputMoney = 10000000;
int period = 24;
double interest = Double.parseDouble("2.4");
int totalInputMoney = inputMoney * period;
double totalInterest = totalInputMoney * interest / 100;
double totalReceiveMoney = totalInterest + totalInputMoney;
DecimalFormat df = new DecimalFormat("₩###,###,###");
%>
<h1>積立金 計算</h1>
<h2>入力された情報</h2>
<p>月 金額 : <%=df.format(inputMoney) %></p>
<p>積立 期間 : <%=period %></p>
<p>年 利子 : <%=interest %></p>
<hr>
<p>総 納入 金額 : <%=df.format(totalInputMoney) %></p>
<p>発生 利子 : <%=df.format(totalInterest) %></p>
<p>総 受領額 : <%=df.format(totalReceiveMoney) %></p>
</body>
</html>
4. Include方式の比較:静的インクルード vs 動的インクルード
共通のヘッダーやフッターをページに含める方法には、「ディレクティブ(地示子)方式」と「アクションタグ方式」があり、その動作原理は大きく異なります。
① ディレクティブ(静的)インクルード:<%@ include file="..." %>
特徴: コンパイル時にドキュメントが「統合」される(静的)。
動作: JSPファイルがJavaソース(サーブレット)に変換される前に、ファイルのコード自体が埋め込まれ、1つのファイルとしてコンパイルされます。
メリット: 含まれる側のJSP(JSPF)で宣言されたJava変数を、含む側のメインJSPでそのまま共有して使用できます。
メインページ (includeDirective.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%-- header.jspf ファイルを include --%>
<h1>include directive(地示子)</h1>
<%@ include file="header.jspf" %>
<div>
<p>本文です。</p>
</div>
<p><%=header %></p> <%-- header.jspfの変数をそのまま使用できる --%>
<%@ include file="footer.jspf" %>
<%--
* directive include の特徴
1. JSPファイルがJavaファイルに変換される際、文書に統合されてコンパイル(静的)
2. 多数のJSPページで共通して使用されるコードを記述する用途
3. 含まれるJSPファイルで宣言した変数を、含むJSPファイルで使用可能
--%>
</body>
</html>
ヘッダー断片 (header.jspf)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<style>
.header{
background-color : lightgreen;
font-size : 200%;
text-align : center;
height : 60px
}
</style>
<%!
String header = "ヘッダー変数";
%>
<div class="header">
ここは header です。
</div>
フッター断片 (footer.jspf)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<style>
.footer {
background-color : lightblue;
text-align : center;
height : 60px;
}
</style>
<div class="footer">
(株) 木コーディング<br>
https://www.mokcoding.co.kr<br>
TEL : 010-xxxx-xxxx
</div>
② アクションタグ(動的)インクルード:jsp:include
特徴: 各ファイルが「個別」にコンパイルされる(動的)。
動作: 親ファイル(actionInclude.jsp)と子ファイル(part.jsp)は統合されず、それぞれ別々にコンパイルされます。実行時に子ファイルの結果(HTML)のみが取り込まれます。
注意点: 別々に処理されるため、子ファイルで定義されたJava変数を親ファイルで使用することはできません。
メインページ (actionInclude.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>action include</title>
</head>
<body>
<h2>action tag include 例</h2>
<div>
<p>header 部分</p>
</div>
<div>
<p>外部ファイル 部分</p>
<jsp:include page="part.jsp"></jsp:include>
<%-- ctrl+shift+/注釈処理 --%>
<%-- <%=header %> --%><%-- part.jspの変数は使用不可能(エラーになる) --%>
<%--
action includeはファイルを包含する機能だが、
親ファイル(actionInclude.jsp)に統合されず、別々にコンパイルされる
--%>
</div>
<div>
<p>footer 部分</p>
</div>
</body>
</html>
サブページ (part.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<h2>part.jsp</h2>
<%!
String header = "part.jsp header";
%>
<%= header %>
5. フォーム(Form)データの伝送とデータ受け取り
クライアント(ブラウザ)から入力されたデータをサーバーに送信し、内蔵オブジェクトである request を用いて抽出する方法です。
① データ入力画面:GET方式 (send.jsp)
form タグの action 属性で送信先 URL を指定。
input の name 属性がデータの Key(パラメータ名) となります。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>データ転送テスト</title>
</head>
<body>
<form action="result.jsp" method="GET">
<P>名前</P>
<input type="text" name="name">
<p>年齢</p>
<input type="number" name="age">
<br><br>
<input type="submit" value="転送">
</form>
</body>
</html>
② データ受信画面 (result.jsp)
request.getParameter("キー名") を使用して、クエリ文字列(Query String)からデータを参照します。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>結果 画面</title>
</head>
<body>
<%
// String getParameter(String name) :
// - requestはformから転送されたデータを取得するparameterを提供
// - request オブジェクトに query string が保存され、 getParameter() でデータを参照
// * GET 方式 url 情報の構造
// http:// - 通信 規約(http or https)
// localhost:8080/ - localhost : 自身の PC の IP, 8080 : ポート番号
// JSP01_SERVLET/ - Context Root(サーバーの基本経路)
// ch12/result.jsp - ページ経路
// ?name=%EB%91%98%EB%A6%AC&age=20 - query string (クエリ文字列)
// requestに保存された parameter : name, age
%>
名前 : <%= request.getParameter("name") %>
年齢 : <%= request.getParameter("age") %>
</body>
</html>
6. JavaBeanとアクションタグの自動バインディング
多くの入力項目があるフォーム(POST方式など)を扱う際、リクエストパラメータを一つずつ抽出するのは非効率です。JSPの jsp:useBean と jsp:setProperty を使用すると、Javaクラスのオブジェクトへデータを一括で自動マッピング(Binding)できます。
① 会員登録フォーム:POST方式 (register.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>会員 情報</title>
</head>
<body>
<h2>会員 加入 ページ</h2>
<form action="info.jsp" method="POST">
<P>アイディ</P>
<input type="text" name="userid" placeholder="アイディ入力"
required>
<p>パスワード</p>
<input type="password" name="password" placeholder="パスワード"
required="required">
<p>Eメール</p>
<input type="email" name="email" placeholder="Eメール入力"
required="required">
<p>Eメール 受信の可否</p>
<input type="radio" name="emailAgree" value="yes"> はい
<input type="radio" name="emailAgree" value="no"
checked="checked">いいえ
<p>自己紹介</p>
<textarea rows="4" cols="30" name="introduce"
placeholder="自己紹介入力" required="required"></textarea>
<input type="submit" value="転送">
</form>
</body>
</html>
② 自動バインディングと出力画面 (info.jsp)
property="*" を指定することで、フォームの name 属性と MemberBean クラスのフィールド名(セッター名)が一致するデータが一度にすべて自動注入されます。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>会員 情報</title>
</head>
<body>
<%
// パラメータを保存する変数名は、parameter nameと同一に作成することを推奨
/* String userid = request.getParameter("userid");
String password = request.getParameter("password");
String email = request.getParameter("email");
String emailAgree = request.getParameter("emailAgree");
String introduce = request.getParameter("introduce"); */
%>
<%-- useBean : Java クラスを JSP 内で活用できるようにマッピング --%>
<jsp:useBean id="member" class="edu.web.ch13.MemberBean"></jsp:useBean>
<%-- setProperty * : request パラメータのすべてのデータを member クラスに Binding --%>
<jsp:setProperty property="*" name="member"/>
<h2>会員 情報 結果</h2>
<p>アイディ : <%=member.getUserid() %></p>
<p>パスワード : <%=member.getPassword() %></p>
<p>Eメール : <%=member.getEmail() %></p>
<p>Eメール 受信の可否 : <%=member.getEmailAgree() %></p>
<p>自己紹介 : <%=member.getIntroduce() %></p>
</body>
</html>
まとめ
本日学習した内容は、将来 Spring Framework や MVCパターンを理解するための非常に重要な土台となります。実務における使い分けの基準として、以下のように整理しました。
- 4大領域(Scope)の使い分け基準
request: ページ間でデータを移動させる(Forward)際の基本領域。不要になったデータは応答後にすぐ消滅するため、メモリ管理において最も安全で推奨される領域です。
session: ログイン情報やカート情報など、「ユーザー個人の状態」を維持する時のみ厳選して使用します(多用するとサーバーメモリを圧迫するため注意)。 - Include方式の賢い選択方法
ディレクティブ(静的)方式 (<%@ include %>): 全ページで共通して使うスタイルシート(CSS)の宣言、環境変数、グローバルなJava変数を一括で管理する場合に最適です。
アクションタグ(動的)方式 (jsp:include): ページの上部(Header)や下部(Footer)など、デザインの枠組みだけをモジュール化して、変数の衝突(重複)を防ぎたい場合に最適です。 - JavaBeanと自動バインディングの意義
request.getParameter() を何行も書く泥臭い作業から解放されました。
フォームの name 属性とJavaクラスの setter を一致させるだけでデータが自動注入される仕組み(DTO / VO パターン)は、今後のウェブ開発における「データ伝送の標準ルール」となるため、確実にマスターしておく必要があります。