6.

Struts JSP タグ完全リファレンス(Struts 1/2 + Spring MVC への移行)

編集
この記事の要点
  • Struts 1 の JSP タグは <html:> (form 系) / <bean:> (値出力) / <logic:> (条件分岐) の 3 系統に分かれる
  • Struts 2 では <s:> 1 つに統一され、OGNL でアクションのプロパティに直接アクセス
  • JSTL + EL でも同じことができるため、新規開発は Struts タグを避けて JSTL を使うのが王道
  • Spring MVC への移行は <form:input> など Spring 専用タグへ 1 対 1 で置き換え可能
  • TLD (Tag Library Descriptor) が欠落していると Unable to find taglib uri エラーになる

Struts JSP タグの概要

Struts はカスタムタグライブラリを提供し、JSP 側で <% %> スクリプトレットを書かずに HTML フォームや繰り返し処理を表現できます。Struts 1 と Struts 2 でタグ体系が大きく異なるため、それぞれ把握する必要があります。

Struts 1 のタグ体系

接頭辞TLD URI用途
htmlhttp://struts.apache.org/tags-htmlHTML フォーム要素
beanhttp://struts.apache.org/tags-beanBean / メッセージ表示
logichttp://struts.apache.org/tags-logic条件分岐・繰り返し
nestedhttp://struts.apache.org/tags-nestedネストプロパティ
tileshttp://struts.apache.org/tags-tilesTiles レイアウト

Struts 1 タグ使用例

<%@ taglib uri="http://struts.apache.org/tags-html"  prefix="html"  %>
<%@ taglib uri="http://struts.apache.org/tags-bean"  prefix="bean"  %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>

<html:form action="/login">
    ユーザー ID: <html:text property="userId"/>
    パスワード: <html:password property="password"/>
    <html:submit value="ログイン"/>
</html:form>

<%-- メッセージ表示 --%>
<logic:messagesPresent>
    <ul>
    <html:messages id="msg">
        <li><bean:write name="msg"/></li>
    </html:messages>
    </ul>
</logic:messagesPresent>

<%-- 繰り返し --%>
<logic:iterate id="user" name="userList">
    <bean:write name="user" property="name"/>
</logic:iterate>

<%-- 条件分岐 --%>
<logic:equal name="user" property="role" value="admin">
    管理者メニュー
</logic:equal>

Struts 2 のタグ体系

Struts 2 では <s:> 接頭辞に統一され、OGNL で Action のプロパティに直接アクセスできます。

<%@ taglib prefix="s" uri="/struts-tags" %>

<%-- フォーム --%>
<s:form action="login" method="post">
    <s:textfield name="userId"   label="ユーザー ID"/>
    <s:password  name="password" label="パスワード"/>
    <s:select    name="role" label="ロール"
                 list="{'admin','user','guest'}"/>
    <s:submit value="ログイン"/>
</s:form>

<%-- 条件 --%>
<s:if test="hasActionErrors()">
    <s:actionerror/>
</s:if>
<s:elseif test="loggedIn">
    ようこそ <s:property value="userName"/>
</s:elseif>

<%-- 繰り返し --%>
<s:iterator value="userList" var="u" status="st">
    <s:property value="#st.index"/>: <s:property value="#u.name"/>
</s:iterator>

<%-- URL 生成 --%>
<s:url action="logout" var="logoutUrl"/>
<a href="${logoutUrl}">ログアウト</a>

<%-- 国際化 --%>
<s:text name="welcome.message"/>

Struts 1 タグ ⇔ Struts 2 タグ対応表

用途Struts 1Struts 2JSTL/Spring MVC
フォーム<html:form><s:form><form:form> (Spring)
テキスト入力<html:text><s:textfield><form:input>
パスワード<html:password><s:password><form:password>
セレクト<html:select><s:select><form:select>
サブミット<html:submit><s:submit><button type="submit">
値出力<bean:write><s:property>${var} / <c:out>
繰り返し<logic:iterate><s:iterator><c:forEach>
条件 (=)<logic:equal><s:if test=""><c:if test="">
エラー表示<html:errors><s:fielderror><form:errors>

TLD (Tag Library Descriptor) とは

カスタムタグの定義ファイルです。JAR 内の META-INF/*.tld に同梱され、JSP コンテナがタグ名とハンドラクラスを対応付けるのに使います:

<!-- struts-html.tld の抜粋 -->
<taglib>
    <tlib-version>1.3</tlib-version>
    <short-name>html</short-name>
    <uri>http://struts.apache.org/tags-html</uri>

    <tag>
        <name>text</name>
        <tag-class>org.apache.struts.taglib.html.TextTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>property</name>
            <required>true</required>
        </attribute>
    </tag>
</taglib>

よくあるエラー

1. Unable to find taglib uri

org.apache.jasper.JasperException: /WEB-INF/views/login.jsp(2,1)
PWC6188: The absolute uri: http://struts.apache.org/tags-html cannot be
resolved in either web.xml or the jar files deployed with this application

原因と対処:

  • struts-taglib.jar (Struts 1) または struts2-core.jar (Struts 2) が WEB-INF/lib/ にない → 追加
  • uri の綴り間違い → 公式の URI に合わせる
  • JAR バージョン違い (1.3 系で 1.2 系の uri 等) → JAR と uri を一致させる

2. property を見つけられない (No getter method for property)

javax.servlet.jsp.JspException: No getter method for property userId
of bean org.apache.struts.taglib.html.BEAN

ActionForm に getUserId() / setUserId(String) がないため。Bean 規約に従って getter/setter を追加。

Spring MVC への移行例

Struts 1 のフォームを Spring MVC へ書き換えるパターン:

<%-- Struts 1 --%>
<html:form action="/login">
    <html:text property="userId"/>
    <html:password property="password"/>
    <html:submit value="ログイン"/>
    <html:errors/>
</html:form>

<%-- Spring MVC --%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<form:form action="login" modelAttribute="loginForm">
    <form:input path="userId"/>
    <form:password path="password"/>
    <button type="submit">ログイン</button>
    <form:errors path="*" cssClass="error"/>
</form:form>

JSTL のみで Struts タグを置き換える

Struts タグを使わず JSTL + 標準 HTML だけで書く方が、移植性が高くお勧めです:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<form action="${pageContext.request.contextPath}/login" method="post">
    <input type="text"     name="userId"   value="${param.userId}"/>
    <input type="password" name="password"/>
    <button type="submit">ログイン</button>
</form>

<c:if test="${not empty errors}">
    <ul class="error">
        <c:forEach var="e" items="${errors}">
            <li><c:out value="${e}"/></li>
        </c:forEach>
    </ul>
</c:if>

FAQ

Q: Struts 1 と Struts 2 のタグを同じ JSP に混在できる?
A: 技術的には可能ですが避けるべき。Tag handler の競合や OGNL/EL の混在で問題が起きやすい。移行するならページ単位で書き換える。

Q: TLD ファイルは web.xml に書く必要がある?
A: Servlet 2.4+ では JAR の META-INF に同梱した TLD が自動検出されるため不要。古いコードに残っているだけ。

Q: カスタムタグを自作したい
A: JSP 2.0 以降は .tag ファイル (WEB-INF/tags/ に配置) で簡単に作成可能。Java クラス + TLD を書く必要はない。

関連項目

  • JSTL — JSP 標準タグライブラリ
  • EL (Expression Language) — JSP/Servlet 標準の式言語
  • Spring MVC form タグ — 移行先の標準
  • Thymeleaf — タグライブラリ不要の HTML テンプレート
編集
Post Share
子ページ
  1. logic:messagesPresent
同階層のページ
  1. 導入方法
  2. struts-config.xmlの説明
  3. ActionForm
  4. Action
  5. エラー一覧
  6. JSP タグ
  7. カスタムタグ(tablib)

最近更新/作成されたページ