Struts2メモ
提供: Astarisk Works Wiki
Struts2のちょっとしたことをまとめます。
目次 |
特徴
- Webwork2を元に開発された
- アノテーションを使えば設定ファイルでアクションマッピングを記述しなくてもいい。参考:@いう間にWebアプリを作れる「Struts 2」入門 - @IT
- バージョン2.1.6以降はConventionプラグインの規約に従えばアノテーションも書かずにリクエストがアクションにマッピングできる。
- 個人的にはstruts.xmlで集中管理した方がいいと思うが...
- ActionServletがなくなり、フィルターでリクエストがディスパッチされるようになった。
基本構成
Struts2の基本構成は次の通り。 基本的にはJ2EEの規約に従ったディレクトリ構成にStruts2に必要な設定ファイルとライブラリのJarファイルを配置する。
libディレクトリの中のjarファイルは起動に最低限必要なもの。
アプリケーションのルートディレクトリ/
└ WEB-INF/
├ web.xml
├ classes/
│ └ struts.xml
└ lib/
├ commons-fileupload-1.2.1.jar
├ freemarker-2.3.13.jar
├ ognl-2.6.11.jar
├ struts2-core-2.1.6.jar
└ xwork-2.1.2.jar
- 設定ファイル
- 設定ファイルは次の2つ
- web.xml
- struts.xml
web.xmlに最低限必要な設定
Struts1はサーブレットとしてディスパッチャーが実装されていたが、Struts2ではフィルターとして実装されている。従って、その設定がWeb.xmlに必要となる。
welcome-file-listの設定は必須ではないが、良い習慣としては指定しておいた方が良いと思う。
<?xml version="1.0" encoding="UTF-8"?> <web-app id="MyGTD" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Struts Blank</display-name> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
フィルタークラスは2.1.3まではorg.apache.struts2.dispatcher.FilterDispatcherを使うようになっていたが、それ以降はDeprecatedになっていて代わりに次のクラスを使うように変わっている。
- StrutsPrepareAndExecuteFilter
ただし、2.1.6のStrutsPrepareAndExecuteFilter は2バイト文字が正しく処理できず化けてしまう不具合がある。
タグライブラリ
Struts2のカスタムタグライブラリの設定
<jsp-config>
<taglib>
<taglib-uri>/struts-tags</taglib-uri>
<taglib-location>/WEB-INF/struts-tags.tld</taglib-location>
</taglib>
</jsp-config>
Spring Frameworkの設定
まずは設定ファイルの場所をコンテキストパラメーターに設定する。
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext.xml</param-value> </context-param>
Springはアプリケーション起動時にリスナーによって起動されるの使う場合には追加する。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
Tilesの設定
Tilesを使うときにもリスナーの設定が必要
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
<s:form>タグが勝手に要素をテーブルに入れるのをやめる</s>
strutsのUIテーマをsimpleに設定すればよい。全体的に設定するには次の様にする。 struts.xmlで設定するには次の行を追加する。
<constant name="struts.ui.theme" value="simple"/>
struts.propertiesに設定するには次の行を追加する。
struts.ui.theme=simple
あるformの中だけ限定的に設定したいなら、次の様にタグのtheme属性を追加する。
<s:form action="hogehoge" theme="simple"> <%-- フォームの実装 --%> </s:form >
日付をフォーマットする
<s:date>タグを使う。次の例はentryTimeの値をフォーマットして出力する例。
<s:date name="entryTime" format="yyyy/MM/dd HH:mm"/>
フォーマットはリソースの中に書いておくこともできる。その場合はgetTextを使って取り出す。
<s:date name="entryTime" format="%{getText('format.dateTime')}"/>
リソースには次のように定義しておく。
format.dateTime=yyyy/MM/dd HH:mm
値をフォーマットする
日付だけでなく文字列や数値をフォーマットするときにはリソースに次のように定義しておき、
format.date_medium={0,date,medium}
format.date_ymd={0,date,yyyy/MM/dd}
format.date_time={0,date,yyyy/MM/dd hh:mm}
format.number_money={0,number,#,##0}
次の様に書くと自在にフォーマットできる。内部ではMessageFormatクラスが使われているよう。
<s:text name="format.number_money">
<s:param name="value" value="salesPrice"/>
</s:text>円
<s:text name="format.date_ymd">
<s:param name="value" value="salesDate"/>
</s:text>
バリデーション
ZeroConfiguration
Conventionプラグインを使うとアノテーションも書かずにリクエストがアクションにマッピングできる、というかされる。
次の条件を満たすクラスをアクションクラスと認識する。
- パッケージ名にがstruts、struts2、action、actionsという階層が含まれている。
- com.opensymphony.xwork2.Actionインターフェイスを実装している
- クラス名が「Action」で終わっている
たとえば、com.example.action.ExampleActionクラスはcom.opensymphony.xwork2.ActionインターフェイスをインプリしていればActionクラスと認識される。
また、com.example.action.hoge.ExampleActionクラスもcom.opensymphony.xwork2.ActionインターフェイスをインプリしていればActionクラスと認識される。
リクエスとのマッピングはまず例を示した方がわかりやすい。なお、リクエストの末尾のactionは省略可能。
| リクエストパス(コンテキストルート以下) | リクエストに対応するアクションクラス名 |
|---|---|
| /example.action | com.example.action.ExampleAction |
| /hoge</span/example.action | com.example.action.hoge.ExampleAction |
| /hoge/uge/hello-world.action | com.example.action.hoge.uge.HelloWorldAction |
ルールをまとめると次の通り。リクエストの末尾(最後の/以降の*.actionの*の部分)
- コンテキストルートからの相対パス階層はパッケージで最初のstruts、struts2、action、actions階層以下のサブパッケージに対応づけられる。
- アクション名の頭文字を大文字にしActionをつけたクラスをリクエストに対応づける
- アクション名がハイフンを含んでいればそれを単語の切れ目として各単語の頭文字を大文字にしたクラスを対応づける
リクエストにマッピングされるクラスが特定されるとそのクラスのexecuteメソッドを実行し、リザルトコードを元に今度はVIEWになるファイルを特定する。
ではそのリザルトとVIEWを構成するファイルとのマッピングはどうなっているのか?
それは次のルールで対応づけられる。
- アクション名-リザルトコード.jsp というnameのjspにマッピングする
- jspが見つからなければ次の順番に探す
- HTMLファイル(*.html)
- Velocityテンプレート(*.vm)
- freemarkerテンプレート(*ftl)