atwiki-logo
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このウィキの更新情報RSS
    • このウィキ新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡(不具合、障害など)
とりあえず雑記帳(跡地)
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
とりあえず雑記帳(跡地)
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
とりあえず雑記帳(跡地)
  • 新規作成
  • 編集する
  • 登録/ログイン
  • 管理メニュー
管理メニュー
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • このウィキの全ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ一覧(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このwikiの更新情報RSS
    • このwikiの新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡する(不具合、障害など)
  • atwiki
  • とりあえず雑記帳(跡地)
  • Struts 2

とりあえず雑記帳(跡地)

Struts 2

最終更新:2013年03月12日 22:29

fujiyan

- view
管理者のみ編集可
とりあえず、Struts 2.3.8現在の内容です。
  • 環境構築
  • まずは最小構成を目指す
    • jarファイル
    • Actionクラス
      • パッケージ
      • クラス
      • メソッドと戻り値
    • JSPファイル
    • web.xmlファイル
    • struts.xmlファイル
    • まとめ
  • Root namespaceとDefault namespace
  • Dynamic Method Invocationの罠
  • Config Browser Plugin
  • Actionクラスのメソッド毎にActionを割り当てたい


環境構築

ダウンロードはここから
Apache Struts Releases
"best available"と付記しているリンク先のファイルをダウンロードします。

パッケージングの種類によって、いくつかのファイルがあります。
"Full Distribution"だと、とんでもない数のファイルが格納されているので、解凍が面倒くさいです。
手っ取り早くjarファイルだけ欲しい場合は、"Essential Dependencies Only"(ファイル名がstruts-x.x.x-lib.zip)をダウンロードしましょう。


まずは最小構成を目指す

参考
Convention Plugin
※Zero Configuration→Codebehind Plugin→Convention Pluginと移り変わっている模様。

最初のサンプルとして
  • 極力少ないjarファイル
  • 極力少ない設定ファイル
で、アプリを作ってみます。

jarファイル

必要なのは
  • asm-x.x.jar
  • asm-commons-x.x.jar
  • commons-fileupload-x.x.x.jar
  • commons-io-x.x.x.jar
  • commons-langx-x.x.jar
  • freemarker-x.x.x.jar
  • javassist-x.x.x.GA.jar
  • ognl-x.x.x.jar
  • struts2-convention-plugin-x.x.x.jar
  • struts2-core-x.x.x.jar
  • xwork-core-x.x.x.jar
の11個。これらをWEB-INF/libに配置します。

Actionクラス

Convention PluginがActionクラスとして認識するクラスは、幾つかの条件があります。

例として、下記のActionクラスを作成してみました。
package jp.fujiyan.strutstest.actions.sub;
 
import com.opensymphony.xwork2.ActionSupport;
 
@SuppressWarnings("serial")
public class TestAction extends ActionSupport {
	private String message;
 
	public String getMessage() {
		return message;
	}
 
	public String execute() throws Exception {
		message = "てすと";
 
		return SUCCESS;
	}
}
 

パッケージ

まずパッケージですが、下記のサブパッケージ名以下に格納されている必要があります。
  • struts
  • struts2
  • action
  • actions
上記の例の場合、jp.fujiyan.strutstest.actions.subなので、用件を満たしています。
なお、上記サブパッケージ以下のパッケージ階層は、そのままActionのnamespaceに対応します。
パッケージ Actionのnamespace
jp.fujiyan.strutstest.actions.sub /sub
jp.fujiyan.strutstest.struts2.foo.bar /foo/bar
jp.fujiyan.strutstest.actions (Default namespace)
コンテキストルートにマッピングさせるつもりで、actions等の直下にActionクラスを配置しても、Root namespaceではなく、Default namespaceに割り当てられます(この仕様はどうなんでしょう…?)。
※Root namespceとDefault namespaceの違いは後述「Root namespaceとDefault namespace」を参照

コンテキストルートにマッピングさせたい場合は、@Namespaceアノテーションで明示的に"/" namespaceを指定することで、Root namespaceにします。

クラス

次にクラスですが、上記サブパッケージに格納されているクラスのうち、下記のいずれかに該当するクラスがActionクラスとして認識されます。
  • クラス名の末尾が"Action"
  • com.opensymphony.xwork2.Actionをimplementsしている
上記の場合、TestActionなので、Actionクラスとして認識されます。

…が、実は、com.opensymphony.xwork2.Actionをimplementsしている、com.opensymphony.xwork2.ActionSupportをextendsしているので、末尾"Action"でなくてもActionクラスとして認識されます。
今回は、定数SUCCESSが使いたかったのでActionSupportをextendsしましたが、何かと便利なので通常はどのActionクラスでもActionSupportをextendsしておきます。

Actionクラス名とURLの対応は下記の通りです。
  • 末尾"Action"は、URLから省かれる
  • 先頭の大文字は、URLでは小文字になる。
  • キャメルケースは、URLではハイフン繋ぎで全て小文字になる。
クラスのFQCN namespace コンテキストルートからの、ActionへのURLパス
jp.fujiyan.strutstest.actions.sub.TestAction /sub /sub/test
jp.fujiyan.strutstest.actions.foo.Sample(com.opensymphony.xwork2.Actionをimplements) /foo /foo/sample
jp.fujiyan.strutstest.struts2.foo.bar.ExampleBazAction /foo/bar /foo/bar/example-baz

メソッドと戻り値

ActionクラスにString execute()メソッドを定義し、その中に処理を記述します。
execute()の戻り値によって、Action実行後に処理を行うJSPファイルを切り替えることができます。
詳細は後述。

JSPファイル

JSPファイルは、/WEB-INF/contentに格納します。
名前は、Actionクラス名に対応するURL名に、Actionクラスの戻り値の文字列をハイフンで繋いだものにします。
なお、"success"を戻り値とした場合は、JSPファイル名には戻り値の文字列"success"は省略可能です。
namespace階層と、/WEB-INF/content以下のパス階層を合わせておきます。
クラスのFQCN namespace コンテキストルートからの、ActionへのURLパス 戻り値 処理されるJSPファイル
jp.fujiyan.strutstest.actions.sub.TestAction /sub /sub/test "success" /WEB-INF/content/sub/test.jsp(test-success.jspでも可)
jp.fujiyan.strutstest.actions.sub.TestAction /sub /sub/test "error" /WEB-INF/content/sub/test-error.jsp
jp.fujiyan.strutstest.struts2.foo.bar.ExampleBazAction /foo/bar /foo/bar/example-baz "abc" /WEB-INF/content/foo/bar/example-baz-abc.jsp
今回は、successのみなので、/WEB-INF/content/sub/test.jspを用意しました。
<%@page contentType="text/html; charset=utf-8"%>
 
<!DOCTYPE html>
<html lang="ja">
<head>
</head>
<body>
メッセージ:${message}
</body>
</html>
 

web.xmlファイル

Struts 2のFilterだけの、最小定義です。
念のため、Dynamic Method Invocationを無効にしています。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="StrutsTest" version="3.0">
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
      <param-name>struts.enable.DynamicMethodInvocation</param-name>
      <param-value>false</param-value>
    </init-param>
  </filter>
 
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
 

struts.xmlファイル

…は、不要です。

まとめ

Eclipseのワークスペースのイメージです。

実行イメージです。


Root namespaceとDefault namespace

参考
Namespace Configuration

Root namespaceとDefault namespaceは、似ているようで全然違うので気をつけましょう。

Root namespaceは、その名の通り、ルートコンテキスト"/"に対応するnamespaceです。
一方、Default namespaceは、リクエストに対応するActionが、指定されたURLに対応するnamespaceに存在しない場合の、代替の検索場所となります。

例えば、/sub/test.actionというリクエストがあった場合、"/sub" namespaceにTestActionクラスが存在しなかった場合、Default namespaceのTestActionクラスが呼び出されます。
/sub/aa/test.actionでも、/sub/aa/bbb/test.actionでも、該当namespaceにActionクラスが無ければ、Default namespaceのTestActionクラスが呼び出されます。
言い換えれば、Default namespaceとは「グローバルなnamespace」とも言えます。

そのため、Default namespaceのActionは、思わぬURLで呼び出される場合があるので、よく計画した上で利用しましょう。
考えるのが面倒くさい場合は、利用を避けるのがベターでしょう。


Dynamic Method Invocationの罠

参考
Bruce Phillips Blog on Java, ColdFusion, Flex and Spry: Struts 2 Security Vulnerability - Dynamic Method Invocation

Struts 2で、Actionクラスの数を減らすためにDynamic Method Invocation(DMI)を使いたくなりますが、よく注意しないと大変なことになるお話。
古い記事ですが、念のため。

Dynamic Method Invocationを有効にすると、Actionクラスの引数無しpublicメソッドが
"!" + (メソッド名).action
で呼び出すことが出来ます。
そのため、本来公開させるつもりではなかったメソッドまで、外部から呼び出すことが出来ます。

「そんなの、どーせエラーになるだけでしょ?」と思いますが、そのとき出力されるエラーメッセージが曲者なのです。
想定外のメソッドの呼び出しのため、当然、戻り値に対応するJSPも準備されていないので、404エラーのメッセージの詳細に
No result defined for action (アクションクラス名) and result (メソッドの戻り値)
と出力されます。「アクションクラスからの戻り値に対応する結果は定義されていません」ということです。

これが、呼び出したメソッドが、例えばgetPassword()というパスワードを返すメソッドだった場合、その戻り値であるパスワードがモロに(メソッドの戻り値)の部分に乗っかってしまうのです。

これを防ぐために、設定ファイルにて、DMIで呼び出し可能なメソッドを制限することができます。
ただ、そのために設定ファイルの記述をするくらいなら、そもそもDMI要らないよね、という話にもなってきたり。

もちろん、DMIは便利な機能でもあるので、全く使うな、というわけでもないですが、気を使うのが面倒なら無効にしておきましょう。


Config Browser Plugin

Convention Pluginを使えば、struts.xmlを記述しなくていいので手間は省けますが、逆にどのようにActionとURLがマッピングされているかが一目で把握できません。
そこで、このConfig Browser Pluginが用意されています。

設定は簡単で、
  • struts2-config-browser-plugin-x.x.x
を/WEB-INF/libに格納するだけです。あとはサーバ起動後に
http://localhost:8080/(コンテキスト名)/config-browser/index.action
にアクセスするだけです。

最初のサンプルの"/sub" namespaceのActionを表示してみました

特に、想定外のマッピングがされてしまっている場合の状況把握に役立ちます。
…が、全てのマッピングを晒してしまうので、通常ユーザーに公開したくない、管理画面用のAction等も知られてしまい、クラッキングの手掛かりとなってしまう可能性があります。
なので、あくまでデバッグ利用にとどめ、プロダクション環境にはConfig Browser Pluginは省いたほうがイイかもしれないですね。


Actionクラスのメソッド毎にActionを割り当てたい

例えば、あるデータの
  • 登録
  • 更新
  • 削除
  • 参照
といったアクションは、関連性が高いので、1つのクラスに納めたほうが見通しがイイですね。処理も似てますし。
ということで、1つのActionクラスのメソッド毎にActionを割り当てたくなりますが、DMIは無効が基本なので、地道にマッピングを記述していきます。
折角Convention Pluginを使うので、struts.xmlを記述せずに、アノテーションで乗り切って見ます。

jp.fujiyan.strutstest.actions.sub.TestAction
package jp.fujiyan.strutstest.actions.sub;
 
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
 
import com.opensymphony.xwork2.ActionSupport;
 
@SuppressWarnings("serial")
@Result(name="success", location="test.jsp")
public class TestAction extends ActionSupport {
	private String testMessage;
	private String inputValue;
 
	public void setInputValue(String inputValue) {
		this.inputValue = inputValue;
	}
 
	public String getInputValue() {
		return inputValue;
	}
 
	public String getTestMessage() {
		return testMessage;
	}
 
	@Action(value="show-test")
	public String show() throws Exception {
		testMessage = "開始";
 
		return SUCCESS;
	}
 
	@Action(value="submit-test")
	public String submit() throws Exception {
		testMessage = "結果「" + inputValue + "」";
 
		return SUCCESS;
	}
}
 

/WEB-INF/content/sub/test.jsp
<%@page contentType="text/html; charset=utf-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
 
<!DOCTYPE html>
<html lang="ja">
<head>
</head>
<body>
<s:form action="submit-test">
<s:textfield name="inputValue" label="値"/>
<s:submit value="実行"/>
</s:form>
メッセージ:${testMessage}
</body>
</html>
 

/sub/show-test.actionで初期表示を行い、/sub/submit-test.actionでフォーム入力の送信結果を表示します。

初期表示

↓
テキストボックスに入力してsubmit

@Actionアノテーションを使って、show()にshow-test.actionを、submit()にsubmit-test.actionを割り当てています。
Actionを記述する際に、先頭に"/"が無いので、NamespaceはActionクラスが属するNamespaceになります。
この場合は、"/sub" Namespaceになります。

@Actionアノテーションだけだと、それぞれのActionの実行後に呼び出されるJSPは
Action JSP
/sub/show-test.action /WEB-INF/content/sub/show-test-success.jsp
/sub/submit-test.action /WEB-INF/content/sub/submit-test-success.jsp
となり、Action毎にJSPが必要になってしまいます。
そのため、@Resultアノテーションで、TestActionクラス全てのメソッドについて、"success"の場合は/WEB-INF/content/sub/test.jspを実行するように指定しています。
「Struts 2」をウィキ内検索
LINE
シェア
Tweet
添付ファイル
  • struts2-001.png
  • struts2-002.png
  • struts2-003.png
  • struts2-004.png
  • struts2-005.png
とりあえず雑記帳(跡地)
記事メニュー

メニュー

  • トップページ
  • コメント
  • とりあえずインターフェース入門
  • Yesod
  • Haskell
  • Slim3
  • JavaScript
  • Google App Engine
  • Android
  • Facebook
  • GWT
  • OpenSocial
  • Struts 2
  • Subversion
  • Apache
  • JSONIC
  • Flex

  • WebコミックLibraryについて

公式サイト

  • Yesod
  • Haskell
  • Slim3
  • JavaScript - MDN
  • App Engine for Java
  • Android Developers
  • Google Web Toolkit
  • Struts
  • OpenSocial
  • OSDE

  • ToDo

ここを編集
記事メニュー2
間違いの御指摘は
コメントまでm(_ _)m

更新履歴

取得中です。


ここを編集

総数: -
本日: -
昨日: -
人気記事ランキング
  1. WebコミックLibraryについて
  2. Slim3/環境構築とプロジェクト作成
もっと見る
最近更新されたページ
  • 4342日前

    Haskell
  • 4342日前

    Yesod
  • 4342日前

    トップページ
  • 4452日前

    メニュー
  • 4453日前

    Struts 2
  • 4479日前

    コメント
  • 4648日前

    Google App Engine
  • 4685日前

    Slim3/環境構築とプロジェクト作成
  • 4710日前

    Google App Engine/キャッシュの計画
  • 4720日前

    Slim3/文字列の部分一致検索とページング
もっと見る
人気記事ランキング
  1. WebコミックLibraryについて
  2. Slim3/環境構築とプロジェクト作成
もっと見る
最近更新されたページ
  • 4342日前

    Haskell
  • 4342日前

    Yesod
  • 4342日前

    トップページ
  • 4452日前

    メニュー
  • 4453日前

    Struts 2
  • 4479日前

    コメント
  • 4648日前

    Google App Engine
  • 4685日前

    Slim3/環境構築とプロジェクト作成
  • 4710日前

    Google App Engine/キャッシュの計画
  • 4720日前

    Slim3/文字列の部分一致検索とページング
もっと見る
ウィキ募集バナー
新規Wikiランキング

最近作成されたWikiのアクセスランキングです。見るだけでなく加筆してみよう!

  1. R.E.P.O. 日本語解説Wiki
  2. VCR GTA3まとめウィキ
  3. ガンダムGQuuuuuuX 乃木坂46部@wiki
  4. ドタバタ王子くん攻略サイト
  5. ありふれた職業で世界最強 リベリオンソウル @ ウィキ
  6. STAR WARS ジェダイ:サバイバー攻略 @ ウィキ
  7. 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  8. アサシンクリードシャドウズ@ ウィキ
  9. パズル&コンクエスト(Puzzles&Conquest)攻略Wiki
  10. SYNDUALITY Echo of Ada 攻略 ウィキ
もっと見る
人気Wikiランキング

atwikiでよく見られているWikiのランキングです。新しい情報を発見してみよう!

  1. アニヲタWiki(仮)
  2. ストグラ まとめ @ウィキ
  3. ゲームカタログ@Wiki ~名作からクソゲーまで~
  4. 初音ミク Wiki
  5. oblivion xbox360 Wiki
  6. 発車メロディーwiki
  7. 機動戦士ガンダム バトルオペレーション2攻略Wiki 3rd Season
  8. 検索してはいけない言葉 @ ウィキ
  9. Grand Theft Auto V(グランドセフトオート5)GTA5 & GTAオンライン 情報・攻略wiki
  10. SDガンダム ジージェネレーションクロスレイズ 攻略Wiki
もっと見る
全体ページランキング

最近アクセスの多かったページランキングです。話題のページを見に行こう!

  1. 魔獣トゲイラ - バトルロイヤルR+α ファンフィクション(二次創作など)総合wiki
  2. 参加者一覧 - ストグラ まとめ @ウィキ
  3. フェルシー・ロロ - アニヲタWiki(仮)
  4. サーヴァント/一覧/クラス別 - Fate/Grand Order @wiki 【FGO】
  5. RqteL - ストグラ まとめ @ウィキ
  6. ロスサントス警察 - ストグラ まとめ @ウィキ
  7. 掲示板(時限)/ジークアクス - 機動戦士ガンダム バトルオペレーション2攻略Wiki 3rd Season
  8. ロスサントス救急救命隊 - ストグラ まとめ @ウィキ
  9. 発車メロディー変更履歴 - 発車メロディーwiki
  10. 揚げバター - アニヲタWiki(仮)
もっと見る

  • このWikiのTOPへ
  • 全ページ一覧
  • アットウィキTOP
  • 利用規約
  • プライバシーポリシー

2019 AtWiki, Inc.