ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
カスタムタグとは
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 エスケープして出力 --%>
<bean:write name="user" property="name" />
<%-- HTML エスケープしない (XSS 注意) --%>
<bean:write name="user" property="bio" filter="false" />
<%-- 日付フォーマット --%>
<bean:write name="user" property="createdAt" format="yyyy/MM/dd HH:mm" />
<%-- メッセージリソースから取得 --%>
<bean:message key="label.username" />
<%-- スコープ変数を新規定義 --%>
<bean:define id="total" value="<%= request.getAttribute("count") %>" />
${total}
html タグ (フォーム生成)
<%-- ActionForm "loginForm" にバインドされたフォーム --%>
<html:form action="/login" focus="username">
<%-- ActionForm.getUsername() / setUsername() に紐付く --%>
Username: <html:text property="username" size="20" maxlength="50" />
Password: <html:password property="password" size="20" />
<%-- チェックボックス --%>
<html:checkbox property="rememberMe" /> Remember me
<%-- セレクトボックス (options タグでループ) --%>
<html:select property="country">
<html:options collection="countries" property="code" labelProperty="name" />
</html:select>
<%-- メッセージリソース連動の submit --%>
<html:submit><bean:message key="button.login" /></html:submit>
<%-- エラーメッセージ表示 --%>
<html:errors />
</html:form>
生成される HTML 例:
<form name="loginForm" method="post" action="/app/login.do">
<input type="text" name="username" maxlength="50" size="20" value="" />
<input type="password" name="password" size="20" value="" />
<input type="checkbox" name="rememberMe" value="on" />
<select name="country">
<option value="JP">Japan</option>
<option value="US">United States</option>
</select>
<input type="submit" value="Login" />
</form>
logic タグ (条件分岐 / 繰り返し)
<%-- ユーザがログイン済の場合のみ表示 --%>
<logic:present name="user">
Welcome, <bean:write name="user" property="name" />
</logic:present>
<%-- 逆: 未ログインのみ --%>
<logic:notPresent name="user">
<a href="/login.do">Login</a>
</logic:notPresent>
<%-- 値の比較 --%>
<logic:equal name="user" property="role" value="ADMIN">
<a href="/admin.do">Admin Panel</a>
</logic:equal>
<%-- リストの繰り返し --%>
<table>
<logic:iterate id="item" name="items" type="com.example.Item">
<tr>
<td><bean:write name="item" property="id" /></td>
<td><bean:write name="item" property="name" /></td>
<td><bean:write name="item" property="price" /></td>
</tr>
</logic:iterate>
</table>
nested タグ (ネスト型 Bean)
ActionForm のプロパティが「Bean のリスト」のような場合に、ネストを意識せず書ける糖衣構文。
<%-- itemsForm.items[i].name にバインド --%>
<nested:form action="/save">
<nested:iterate property="items">
<nested:text property="name" />
<nested:text property="price" />
</nested:iterate>
<html:submit value="Save" />
</nested:form>
<%-- 内部で 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):
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>ex</short-name>
<uri>http://example.com/tags</uri>
<tag>
<name>greeting</name>
<tag-class>com.example.tags.GreetingTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
JSP から使用:
<%@ taglib uri="http://example.com/tags" prefix="ex" %>
<ex:greeting name="Taro" />
<%-- → 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" %>
<div style="border:1px solid ${color}; padding:1em">
<h3>${title}</h3>
<jsp:doBody />
</div><%@ taglib tagdir="/WEB-INF/tags" prefix="my" %>
<my:card title="お知らせ" color="#0066cc">
これは本文です。
</my:card>
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 マッピング不一致が典型原因です。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
- 導入方法
- struts-config.xmlの説明
- ActionForm
- Action
- エラー一覧
- JSP タグ
- カスタムタグ(tablib)
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?