Struts2に触れよう! その1(HelloWorldサンプル編)
Strutsに関しては、数年前にStrutsのコードを少し追っかけた程度ですっかり忘れてます。まったくもって知識真っ白な状態なので、StrutsからStruts2になってどう変わったとかはまったく分かりません!ってな状態ですが、とりあえず触ってみることに。
まずは、動かしてみようということで、とりあえずstruts-2.0.6-all.zipをダウンロード。
まずはサンプルから。やっぱり最初はHellowWorldでしょう。
eclipse上でTomcatプロジェクトをプロジェクト名example01で新規作成し、struts-2.0.6/apps/struts2-blank-2.0.6.warを解凍して、まるっとインポート。ビルドパスの構成で、/WEB-INF/lib/配下のjarをライブラリに追加し、ソースフォルダを/WEB-INF/src/javaに変更。
Tomcatを起動し、
http://localhost:8080/example01/example/HelloWorld.action
にアクセスすると、Struts is up and running ...と書かれた画面が表示。
とりあえず、動いたのでコードを見てみますか。
今回使われてるのは以下のもの。
WEB-INF/web.xml WEB-INF/classes/struts.xml WEB-INF/classes/example.xml WEB-INF/classes/example.ExampleSupport.class WEB-INF/classes/example.HelloWorld.class WEB-INF/classes/example/package.properties WEB-INF/classes/example/package_es.properties example/HelloWorld.jsp
[web.xml]
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter>
org.apache.struts2.dispatcher.FilterDispatcherがリクエストの受け口なのね。ServletじゃなくてFilterになってるもよう。
で、アクションをstruts.xmlに定義。今回はstruts.xmlにインクルードされたexample.xmlが実際の定義情報。
<action name="HelloWorld" class="example.HelloWorld"> <result>/example/HelloWorld.jsp</result> </action>
"HelloWorld"のアクションの場合、example.HelloWorldのクラスがインスタンス化されて、execute()メソッドが実行された結果、/example/HelloWorld.jspが呼び出されるってな事。
[example.HelloWorld.java]
com.opensymphony.xwork2.ActionSupport △ | example.ExampleSupport △ | example.HelloWorld
継承関係はこんな感じ。
アクションがサブミットされるとActionSupport#execute()が呼ばれます。HelloWorld#execute()でオーバーライドしてるので、実際に呼ばれるのはこいつ。
public String execute() throws Exception { setMessage(getText(MESSAGE)); return SUCCESS; }
getText()でメッセージを取得し終了。
[example/HelloWorld.jsp]
HelloWorld.javaで取得したメッセージを
<h2><s:property value="message"/></h2>
で表示して終了。
流れ的には以上なんですが、ActionSupport#getText()の動きがいまいち不明。
package.propertiesからメッセージを取得しているようだけど、どこにも"package"なんか定義していないし、"request_locale"リクエストパラメータでロケールの切り替えも行っているようだし。
まずは、ロケールの切り替えをどこで行ってるかを追いかけることに。getText()を遡っていくと、
com.opensymphony.xwork2.interceptor.I18nInterceptor public static final String DEFAULT_PARAMETER = "request_locale"; protected String parameterName = DEFAULT_PARAMETER;
で定義されてるから、"request_locale"って文字列がロケール指定用の予約語になってるっぽい。protected指定だから変更できそう。必要性はないだろうけど。
続いて、package.propertiesをどう指定してるのかを追いかけることに。
com.opensymphony.xwork2.util.LocalizedTextUtil#findText() String packageName = basePackageName + ".package";
どうやらこいつも予約語っぽい。ソースをざっと見た感じ、{パッケージ}/{クラス名}.propertiesがなければ、{パッケージ}/package.propertiesを見に行くっぽい。
ためしに、HelloWorld.propertiesを用意したらこっちを優先に読みにいきました。
あとは、java.util.ResourceBundleでpropertiesファイルを読みにいってるようなので、ロケールによって、package.propertiesとpackage_es.propertiesを切り替えているもよう。