Struts2を使った開発とはどんなものなのか。
まずはプロジェクトを新規作成してみよう。
なお、今後単に Struts と記述した場合には Struts2 を指すものとする。
明示的に Struts1 / Struts2 と記す場合もある。
今回は、JSPではなくVelocityを使う。
Struts2はどちらにも対応している。
参考ページ : Velocityのススメ
Velocityで使用するテンプレートファイルのことを
以下VMファイルを記述する。これは Velocity Macro の略。
ダウンロードするファイルは以下。
Struts2 - Full Distribution をダウンロードしておけば問題なし
Velocity - Engine, Tools の両方をダウンロード
そしたら恒例のWebアプリケーション構成を作成。
これは自由だが、僕は大体以下のようにしている。
Project Root | |-- web | |-- WEB-INF | | |-- classes | | |-- lib | |-- web.xml | |-- src | |-- struts.xml | |-- Javaソース
プロジェクトルートがあり、その直下にwebディレクトリを作成。
ここが、Webアプリケーションサーバから見た docBase になる。
src 以下にはJavaのソースを置くが、classファイルはbin以下ではなく
web/WEB-INF/class 以下に出力するようにする。
そして src の直下に struts.xml を配置する。
これが Struts2 のメイン設定ファイルとなる。
WEB-INF/lib 以下に最低限必要なファイルは以下。
以下も必要。
以下、Velocity関連。
Struts2 を使うためには、最低限以下の記述が必要。
<?xml version="1.0" encoding="UTF-8" ?>
<web-app>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
まずはフィルタの定義。
そしてマッピングの定義。
今回は、全てのURLを struts2 フィルタに通すようにする。
servlet ではなく filter を使うのは、その方が柔軟な対応が可能だから。
最近のWebアプリケーションフレームワークは大抵 filter である。
struts.xml の中身は以下のような感じ。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="lrd" extends="struts-default">
<action name="main" class="org.limy.lrd.web.LrdAction">
<result type="velocity">/index.vm</result>
</action>
</package>
</struts>
struts がルート要素。
package が基本となるサブ要素で、小さなプロジェクトならば
これが一つだけあれば良い。
package#name はパッケージ名。
特に意味は無いが、複数パッケージを使う場合には
それぞれがユニークである必要がある。
extends="struts-default" は見た通り、このパッケージで
Struts のデフォルト設定を使うことを意味する。
action はその名の通りアクションを定義したもので、
一つのアクションに対して一つ必要。
アクションとはStruts 1などでも使われていたWebアプリの基本用語。
要するに「何らかの処理」のことをアクションと呼ぶ。
action#name がアクション名。
これは重要で、WebアプリのURLに直結している。
例えば今回の例ならば、
http://HOST/CONTEXT/main.action
がこのアクションに対応するURLとなる。
.action は固定だが、カスタマイズが可能。
struts.properties struts.action.extension=action,jnlp,do struts.action.extension=,
HOST や CONTEXT は任意のものに置き換えること。
action#class が、アクションに対応するJavaクラスの完全限定名。
com.opensymphony.xwork2.ActionSupport を継承したクラスにする。
※ これは必須ではない。アクションを簡単に実装するための便利クラス
result 要素が、アクションの結果を表す。一般的には遷移先のJSP/VMを定義する。
今回の例では一つだが、一つのアクションに複数の result も定義できる。
その場合は以下のようにする。
<result name="error">/hello/Error.jsp</result> <result name="input">/hello/Input.jsp</result>
こうやって、アクションが返した結果によって遷移先を変化させることができる。
アクションクラスの作成は実に簡単。
LrdAction.java
public class LrdAction extends ActionSupport {
public String execute() {
return SUCCESS;
}
public String getMessage() {
return "lrd sample";
}
}
続いてVelocityファイル。
index.vm
<html> <body> ok. $message </body> </html>
う~む、手抜きだ(笑)。
では、実際にユーザがこのWebアプリケーションを使うときの
流れを追ってみる。
今回はWebアプリケーションサーバにTomcatを使う。
まずはここから。
Tomcat起動時や、warファイル配置時など。
struts.xml が読み込まれ、Struts2 の初期化処理が走る。
必要なjarファイルが存在しなかったりした場合はここでエラーになり
Webアプリケーションは起動しない。
Tomcatのコンソール出力やログを見ればエラーメッセージが出力されているはず。
ユーザが以下のURLをブラウザに入力すると、アクションへ処理が移る。
http://HOST/CONTEXT/main.action
struts.xml の設定により、mainアクションに対応するのは LrdAction。
このクラスの execute メソッドが呼ばれる。
public String execute() {
return SUCCESS;
}
このように、SUCCESS を返すだけ。ちなみにこの定数の実体は "success"。
すると再び struts.xml の内容に従う。
<result type="velocity">/index.vm</result>
とある。
このように result#name が省略されていると、それは "success" を意味する。
従って今回はこの result へ遷移する。
/index.vm の内容をブラウザへ表示することになる。
VMファイルもJSPと同じように、基本的にはHTMLをそのまま記述する。
JSPでは値を埋め込むのに <> で括られた「拡張タグ」というものを使用したが
Velocityでは $ で始まる文字を使う。
$message
というのがその箇所。
これはJSPで言うところの
<s:property value="message" />
にあたる。Velocityの方がスッキリしているのがよくわかると思う。
ここで、$message を展開する。
再びアクションクラスに処理が移る。
public String getMessage() {
return "lrd sample";
}
とあるので、$message は lrd sample に展開される。
従来のServlet開発では
といった流れだったが、Struts では
という流れになる。
必要に応じてアクションクラス内に処理が移ることで
JSP時代に必要だった拡張タグという概念は
ほぼ必要なくなったと言って良い。
これがStruts2の基礎。
非常に簡単なことがおわかりいただけたと思う。
もちろんStruts2には他にもたくさんの機能があるが
全て使いこなす必要はない。
最低限ここで説明したことさえ知っておけば、あとは何とかなる。
最後に。
Struts1 には見向きもしなかった僕が、最初に注目したのがWebwork。
これは使える、これこそが本来のフレームワークだと思った。
そしてそれを受け継ぐStruts2。
ネームバリューもあるし、今後JavaのWebアプリを支えていく
重要なフレームワークになることは間違いない。