タイトル: カスタムタグ(tablib)
SEOタイトル: Struts1 カスタムタグ (taglib) 完全ガイド (bean/html/logic/nested)
| この記事の要点 |
|
カスタムタグとは
JSP では HTML タグ風の独自タグを定義して、Java コードを書かずに動的処理を行えます。これをカスタムタグと呼び、関連するタグをまとめた XML 定義ファイルが TLD (Tag Library Descriptor)、それを JSP から使えるようにする宣言が <%@ taglib %> ディレクティブです。
Struts1 では、フォーム生成 / 値出力 / ロジック制御を行うために、以下 4 つの標準タグライブラリが配布されています:
| TLD | 用途 | URI |
|---|---|---|
| bean | Bean プロパティ参照 | http://struts.apache.org/tags-bean |
| html | HTML フォーム生成 | http://struts.apache.org/tags-html |
| logic | 条件分岐 / 繰り返し | http://struts.apache.org/tags-logic |
| nested | ネスト型 Bean 操作 | http://struts.apache.org/tags-nested |
taglib ディレクティブの書き方
JSP の先頭に宣言します。uri は TLD で定義された URI、prefix は JSP 内で使う接頭辞です。
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-nested" prefix="nested" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
WEB-INF/lib/struts.jar 内の META-INF/tlds/ に各 TLD が同梱されており、URI からそのまま解決されます。古い構成では WEB-INF/struts-html.tld を直接 URI 指定するパターンも残っています。
bean タグ (値出力 / 取得)
<%-- リクエスト属性 user.name を HTML エスケープして出力 --%>
<%-- HTML エスケープしない (XSS 注意) --%>
<%-- 日付フォーマット --%>
<%-- メッセージリソースから取得 --%>
<%-- スコープ変数を新規定義 --%>
" />
${total}
html タグ (フォーム生成)
<%-- ActionForm "loginForm" にバインドされたフォーム --%>
<%-- ActionForm.getUsername() / setUsername() に紐付く --%>
Username:
Password:
<%-- チェックボックス --%>
Remember me
<%-- セレクトボックス (options タグでループ) --%>
<%-- メッセージリソース連動の submit --%>
<%-- エラーメッセージ表示 --%>
生成される HTML 例:
logic タグ (条件分岐 / 繰り返し)
<%-- ユーザがログイン済の場合のみ表示 --%>
Welcome,
<%-- 逆: 未ログインのみ --%>
Login
<%-- 値の比較 --%>
Admin Panel
<%-- リストの繰り返し --%>
nested タグ (ネスト型 Bean)
ActionForm のプロパティが「Bean のリスト」のような場合に、ネストを意識せず書ける糖衣構文。
<%-- itemsForm.items[i].name にバインド --%>
<%-- 内部で items[0].name / items[1].name ... と展開される --%>
独自カスタムタグの作り方
標準で足りないときは自作できます。TagSupport を継承し、doStartTag() / doEndTag() を実装、TLD で宣言します。
package com.example.tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
public class GreetingTag extends TagSupport {
private String name;
public void setName(String name) { this.name = name; }
@Override
public int doStartTag() throws JspException {
try {
pageContext.getOut().print("Hello, " + name + "!");
} catch (IOException e) {
throw new JspException(e);
}
return SKIP_BODY;
}
}
TLD ファイル (WEB-INF/example.tld):
1.0
ex
http://example.com/tags
greeting
com.example.tags.GreetingTag
empty
name
true
true
JSP から使用:
<%@ taglib uri="http://example.com/tags" prefix="ex" %>
<%-- → Hello, Taro! --%>
JSP 2.0 タグファイル (Tag File)
Java クラスを書かずに JSP だけでカスタムタグを定義できる仕組み (JSP 2.0+):
<%-- WEB-INF/tags/card.tag --%>
<%@ tag pageEncoding="UTF-8" %>
<%@ attribute name="title" required="true" %>
<%@ attribute name="color" required="false" %>
${title}
<%@ taglib tagdir="/WEB-INF/tags" prefix="my" %>
これは本文です。
JSTL との関係
JSTL (JSP Standard Tag Library) は標準化されたタグライブラリで、Struts1 の logic タグと多くが重複します。JSTL の方が一般的で長期保守されるため、新規 JSP は JSTL を推奨:
| Struts logic | JSTL c タグ |
|---|---|
logic:iterate | c:forEach |
logic:equal | c:if test="${var == 'x'}" |
logic:present | c:if test="${not empty var}" |
bean:write | c:out value="${var}" or ${var} |
Struts1 移行ガイド
Apache Struts1 は 2013 年 4 月 5 日に EOL (End of Life) を迎えており、セキュリティパッチが提供されません。本番システムでまだ使っている場合は段階的移行を強く推奨:
- Spring MVC + Thymeleaf / JSP — 最も普及、エンタープライズ向け
- Struts2 — Struts1 とは別物の OGNL ベース、移行コストは大きい
- Spring Boot + REST + React/Vue — SPA 化を視野に入れるなら
FAQ
Q: tablib と taglib どちらが正しい?
A: 正しくは taglib。「tablib」は誤記が広まったものです。
Q: カスタムタグと EL (Expression Language) はどう違う?
A: EL ${var} は値の取得のみ、カスタムタグはタグとして処理ロジックを内蔵します。両者は併用できます。
Q: TLD が見つからないエラーが出る
A: org.apache.jasper.JasperException: This absolute uri ... cannot be resolved は struts.jar が WEB-INF/lib にない / web.xml の taglib マッピング不一致が典型原因です。