
JSTL(Coreタグライブラリ)入門 – JSP開発の効率化
2025-08-04JSTLとは何か
JavaServer Pages Standard Tag Library(JSTL)は、JSPでよく使用される機能をタグ形式で提供する標準ライブラリです。JSTLを使用することで、スクリプトレット(<% ... %>
)に依存せず、より読みやすく保守性の高いJSPページを作成できます。
JSTLの主な特徴:
- スクリプトコードを減らし、HTMLライクな記述が可能
- ロジックとプレゼンテーションの分離を促進
- 5つのカテゴリに分類されたタグライブラリ
- カスタムタグよりも学習コストが低い
特にCoreタグライブラリは、JSTLの中でも最も基本的で頻繁に使用されるタグセットです。
JSTL Coreタグライブラリの基本
JSTLの導入
JSTLを使用するには、まずJSPページでタグライブラリを宣言する必要があります。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
この宣言により、c:
というプレフィックスでCoreタグライブラリのタグを使用できるようになります。
変数操作タグ
<c:set>
– 変数の設定
スクリプトレットでの変数設定:
<% request.setAttribute("message", "Hello World!"); %>
JSTLを使用した場合:
<c:set var="message" value="Hello World!" scope="request"/>
属性:
var
:変数名value
:設定する値scope
:スコープ(page, request, session, application)
<c:remove>
– 変数の削除
スクリプトレットでの変数削除:
<% request.removeAttribute("message"); %>
JSTLを使用した場合:
<c:remove var="message" scope="request"/>
条件分岐タグ
<c:if>
– 単純な条件分岐
スクリプトレットでの条件分岐:
<% if(user.isAdmin()) { %>
管理者メニューを表示
<% } %>
JSTLを使用した場合:
<c:if test="${user.admin}">
<p>管理者メニューを表示</p>
</c:if>
属性:
test
:評価する条件式
<c:choose>
, <c:when>
, <c:otherwise>
– 複雑な条件分岐
スクリプトレットでのswitch文:
<%
switch(status) {
case 1:
%>
ステータス: 新規
<%
break;
case 2:
%>
ステータス: 処理中
<%
break;
default:
%>
ステータス: 不明
<% } %>
JSTLを使用した場合:
<c:choose>
<c:when test="${status == 1}">
<p>ステータス: 新規</p>
</c:when>
<c:when test="${status == 2}">
<p>ステータス: 処理中</p>
</c:when>
<c:otherwise>
<p>ステータス: 不明</p>
</c:otherwise>
</c:choose>
ループ処理タグ
<c:forEach>
– コレクションの反復処理
スクリプトレットでのループ:
<ul>
<%
List<String> items = (List<String>)request.getAttribute("items");
for(String item : items) {
%>
<li><%= item %></li>
<% } %>
</ul>
JSTLを使用した場合:
<ul>
<c:forEach items="${items}" var="item">
<li>${item}</li>
</c:forEach>
</ul>
属性:
items
:反復処理するコレクションvar
:各要素を参照する変数名varStatus
:ループ状態を保持する変数名(オプション)
インデックスを使ったループ
スクリプトレットでのインデックスループ:
<% for(int i=1; i<=10; i++) { %>
アイテム <%= i %>
<% } %>
JSTLを使用した場合:
<c:forEach var="i" begin="1" end="10">
<p>アイテム ${i}</p>
</c:forEach>
URL関連タグ
<c:url>
– URLの構築
スクリプトレットでのURL構築:
<a href="<%= response.encodeURL("products.jsp?id=" + productId) %>">商品詳細</a>
JSTLを使用した場合:
<a href="<c:url value='products.jsp'>
<c:param name='id' value='${productId}'/></c:url>">商品詳細
</a>
<c:redirect>
– リダイレクト
スクリプトレットでのリダイレクト:
<% response.sendRedirect("home.jsp"); %>
JSTLを使用した場合:
<c:redirect url="home.jsp"/>
例外処理タグ
<c:catch>
– 例外処理
スクリプトレットでの例外処理:
<%
try {
someRiskyOperation();
} catch(Exception e) {
out.println("エラーが発生しました: " + e.getMessage());
}
%>
JSTLを使用した場合:
<c:catch var="exception">
<% someRiskyOperation(); %>
</c:catch>
<c:if test="${not empty exception}">
<p>エラーが発生しました: ${exception.message}</p>
</c:if>
JSTL Coreタグの応用例
テーブル表示の例
スクリプトレットを使用した場合:
<table>
<tr>
<th>ID</th>
<th>名前</th>
<th>価格</th>
</tr>
<%
List<Product> products = (List<Product>)request.getAttribute("products");
for(Product p : products) {
%>
<tr>
<td><%= p.getId() %></td>
<td><%= p.getName() %></td>
<td class="<%= p.getPrice() > 1000 ? "expensive" : "" %>">
<%= p.getPrice() %>円
</td>
</tr>
<% } %>
</table>
JSTLを使用した場合:
<table>
<tr>
<th>ID</th>
<th>名前</th>
<th>価格</th>
</tr>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.id}</td>
<td>${product.name}</td>
<td class="<c:if test='${product.price > 1000}'>expensive</c:if>">
${product.price}円
</td>
</tr>
</c:forEach>
</table>
ページネーションの例
<div class="pagination">
<c:if test="${currentPage > 1}">
<a href="<c:url value='products.jsp'>
<c:param name='page' value='${currentPage - 1}'/>
</c:url>">前へ</a>
</c:if>
<c:forEach var="i" begin="1" end="${totalPages}">
<c:choose>
<c:when test="${i == currentPage}">
<span class="current">${i}</span>
</c:when>
<c:otherwise>
<a href="<c:url value='products.jsp'>
<c:param name='page' value='${i}'/>
</c:url>">${i}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<c:if test="${currentPage < totalPages}">
<a href="<c:url value='products.jsp'>
<c:param name='page' value='${currentPage + 1}'/>
</c:url>">次へ</a>
</c:if>
</div>
JSTL使用時のベストプラクティス
- スクリプトレットとの使い分け
- 表示ロジックにはJSTLを使用
- 複雑なビジネスロジックはServletやJavaクラスに記述
- 適切なスコープの選択
- 変数のスコープは必要最小限に
- デフォルトはpageスコープ
- タグのネストを適切に
- 深すぎるネストは可読性を低下させる
- 複雑な場合はカスタムタグやServletでの処理を検討
- varStatusの活用
- ループの状態(index, count, first, lastなど)を活用
<c:forEach items="${items}" var="item" varStatus="status">
<tr class="${status.count % 2 == 0 ? 'even' : 'odd'}">
<td>${status.index}</td>
<td>${item}</td>
</tr>
</c:forEach>
- HTMLとの混在を明確に
- JSTLタグとHTMLタグが混在する場合、インデントを揃える
- 必要に応じてコメントを追加
JSTLのデバッグ方法
- 変数の内容を出力
<c:out value="${variable}" default="nullです"/>
- varStatusを利用したループデバッグ
<c:forEach items="${items}" var="item" varStatus="status">
<!-- ${status.index}: ${item} -->
</c:forEach>
- 例外情報の取得
<c:catch var="error">
<!-- 問題が発生する可能性のあるコード -->
</c:catch>
<c:if test="${not empty error}">
<p>エラーが発生しました: ${error.message}</p>
</c:if>
JSTL Coreタグライブラリの全タグ一覧
タグ | 説明 | 主な属性 |
---|---|---|
<c:out> | 式の結果を出力 | value, default, escapeXml |
<c:set> | 変数を設定 | var, value, scope |
<c:remove> | 変数を削除 | var, scope |
<c:catch> | 例外をキャッチ | var |
<c:if> | 条件分岐 | test, var, scope |
<c:choose> | 複数条件分岐のコンテナ | – |
<c:when> | choose内の条件分岐 | test |
<c:otherwise> | choose内のデフォルト処理 | – |
<c:forEach> | コレクションまたは固定回数のループ | items, var, begin, end, step, varStatus |
<c:forTokens> | 文字列のトークン分割ループ | items, delims, var, varStatus |
<c:import> | 外部リソースのインクルード | url, var |
<c:url> | URLを構築 | value, var, scope |
<c:redirect> | リダイレクト | url |
<c:param> | URLにパラメータ追加 | name, value |
まとめ
JSTL Coreタグライブラリを活用することで、JSPページからスクリプトレットを大幅に減らし、より読みやすく保守性の高いコードを記述できます。特に条件分岐やループ処理などの制御構造を、HTMLライクなタグ形式で記述できることが最大の利点です。
JSTLを効果的に使用するポイント:
- 表示ロジックに集中し、ビジネスロジックはServletやJavaクラスに分離
- 適切なタグを選択し、ネストを深くしすぎない
- varStatusなどの便利な機能を活用
- URL構築やリダイレクトなどの定型処理を簡潔に記述
JSTL Coreタグライブラリをマスターしたら、次はEL式(Expression Language)を学ぶことで、さらにJSPの記述を簡潔にできます。また、JSTLには他にもフォーマット処理やXML処理、データベースアクセスなどの機能を提供するタグライブラリがありますので、必要に応じて学習を進めてください。