1.

Struts1 struts-bean.tld 完全ガイド (移行推奨)

編集
この記事の要点
  • struts-bean.tld は Struts 1.x が提供する JSP カスタムタグライブラリの 1 つで、ビーン値の出力・国際化メッセージ・変数定義などを担う
  • 宣言は <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
  • 主要タグは <bean:write> / <bean:message> / <bean:define> / <bean:include> / <bean:cookie> / <bean:parameter>
  • Struts 1.x は 2013 年に EOL 宣言、CVE 修正も止まっており本番運用は危険
  • 移行先は Spring MVC + Thymeleaf / Spring Boot / Jakarta EE が定石。bean タグは Thymeleaf の th:text / #{...} に置換

struts-bean.tld とは

Struts 1 系が提供する JSP カスタムタグライブラリの 1 つで、JavaBean のプロパティ表示・国際化メッセージ・各種 HTTP 情報の取得を JSP 上で簡潔に書くために用意されました。WEB-INF/lib/struts.jar 内に META-INF/tlds/struts-bean.tld として同梱され、TLD 定義により <bean:xxx> 形式で呼び出します。

同じ Struts 1 系には他に struts-html.tld(HTML フォーム生成)、struts-logic.tld(条件分岐・反復)、struts-nested.tld(ネストプロパティ)が存在します。bean タグは値出力系を担います。

宣言と使い方

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

<%-- プロパティ値を出力 --%>
<bean:write name="userForm" property="name" />

<%-- メッセージリソースから国際化メッセージ --%>
<bean:message key="welcome.title" />

<%-- リクエストパラメータ --%>
<bean:parameter id="q" name="keyword" />
検索キーワード: <%= q %>

主要タグ一覧

タグ役割主な属性
<bean:write>JavaBean プロパティを HTML エスケープして出力name / property / filter / format
<bean:message>ApplicationResources からメッセージ取得 (国際化)key / arg0..arg4 / bundle
<bean:define>スクリプティング変数として変数を定義id / name / value / scope
<bean:include>指定 URL の応答内容を文字列として取り込みid / page / href / forward
<bean:cookie>リクエストの Cookie を取得id / name / value / multiple
<bean:header>リクエストヘッダー取得id / name / value
<bean:parameter>リクエストパラメータ取得id / name / value / multiple
<bean:page>JSP 暗黙オブジェクト (request / response / session 等) を変数化id / property
<bean:resource>Web アプリのリソースを読み込みid / name / input
<bean:size>Collection / Map / 配列の要素数id / name / property
<bean:struts>Struts の設定オブジェクト (FormBean 定義等) を変数化id / formBean / forward / mapping

典型的なサンプル

<%@ 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" %>

<html:html>
<head><title><bean:message key="page.title" /></title></head>
<body>

<h1><bean:message key="welcome.user" arg0="<%= request.getRemoteUser() %>" /></h1>

<%-- フォーム値出力 (XSS 対策で filter=true がデフォルト) --%>
ユーザー名: <bean:write name="userForm" property="name" /><br />
登録日:     <bean:write name="userForm" property="registeredAt"
                        format="yyyy/MM/dd" /><br />

<%-- 一覧件数表示 --%>
ヒット件数: <bean:size id="hits" name="searchResults" /><%= hits %>件

<%-- 別ページの内容を取り込み --%>
<bean:include id="footer" page="/footer.jsp" />
<%= footer %>

</body>
</html:html>

ApplicationResources.properties (国際化)

# /WEB-INF/classes/ApplicationResources.properties (デフォルト言語)
page.title=メンバー一覧
welcome.user={0} さん、ようこそ
errors.required={0} は必須です

# /WEB-INF/classes/ApplicationResources_en.properties (英語)
page.title=Member List
welcome.user=Welcome, {0}
errors.required={0} is required.

struts-config.xml で <message-resources parameter="ApplicationResources" /> と宣言しておくと、<bean:message key="..." /> でロケールに応じて自動切替されます。

bean:write のセキュリティ属性

属性意味推奨
filterHTML 特殊文字をエスケープ ( デフォルト true )必ず true (省略)。false にすると XSS リスク
formatSimpleDateFormat / DecimalFormat パターン日付・数値表示に
ignorename のビーンが見つからないときエラーを抑制必須ビーンには false

Struts 1.x が EOL である事実

Apache Struts プロジェクトは 2013 年 4 月 5 日付で Struts 1.x の EOL (End of Life) を宣言しており、以後セキュリティパッチも公式リリースされていません。サポート対象は Struts 2.x(こちらも CVE-2017-5638 = Equifax 事件など重大脆弱性が頻発)と、後継の Apache Struts プロジェクトのみです。

  • 2013-04-05 Struts 1 EOL 宣言
  • 2014-04-22 Struts 1.3.10 系で発見された CVE-2014-0114 (ClassLoader 経由 RCE) — 1.x には公式パッチ無し
  • 2024 現在も commons-beanutils 経由の脆弱性が残存している環境が多い

Spring MVC + Thymeleaf への移行マッピング

Struts 1 (bean タグ)Spring MVC + Thymeleaf
<bean:write name="form" property="name" /><span th:text="${form.name}"></span>
<bean:message key="welcome" /><span th:text="#{welcome}"></span>
<bean:define id="x" value="..." />th:with="x=..."
<bean:include page="/foo.jsp" />th:insert="~{foo :: fragment}"
<bean:parameter id="q" name="keyword"/>Controller の @RequestParam
<bean:cookie id="t" name="token"/>Controller の @CookieValue
<bean:size id="n" name="list"/>${#lists.size(list)}

移行が現実的でない場合の暫定策

  • WAF (Web Application Firewall) で攻撃シグネチャをブロック
  • commons-beanutils を 1.9.4 以降に手動アップグレード
  • 外部から到達不能な閉域網に閉じ込める
  • 新規機能開発を止め、リプレース計画と並走させる

FAQ

Q: bean:write の filter="false" は何のため?
A: 既に HTML を含む値 (リッチエディタ出力など) をそのまま出したいとき。サニタイズ済の信頼できる値のみに限定し、生のユーザー入力は絶対に false にしない。

Q: Struts 1 のまま使い続けて大丈夫?
A: イントラ・閉域なら短期延命は可能ですが、公開システムでは廃止が原則。CVE 修正が止まっている時点でコンプライアンス上もリスク。

Q: 移行コストを下げる方法は?
A: JSP → Thymeleaf 変換は機械的に可能な部分が多い。Action クラス → @Controller は手作業中心だが、ActionForm → @ModelAttribute はマッピングが直感的。段階的に URI 単位で移すストラングラーパターンが定石。

編集
Post Share
子ページ

子ページはありません

同階層のページ

同階層のページはありません

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