Struts2に触れよう! その2(Loginサンプル編)
struts2-blank-2.0.6.warに入ってるLoginのサンプル。
http://localhost:8080/example01/example/Login_input.action
にアクセスすると、ユーザ、パスワード入力画面が表示され、適当に入力後、Submitボタン押下でメッセージ画面に遷移。Submit時には、特に、ユーザ、パスワードの妥当性チェックを行っているわけではなく、ただ単に必須チェックを行っているのみ。
今回使われてるのは以下のもの。
WEB-INF/web.xml WEB-INF/classes/struts.xml WEB-INF/classes/example.xml WEB-INF/classes/example.ExampleSupport.class WEB-INF/classes/example.Login.class WEB-INF/classes/example/Login-validation.xml WEB-INF/classes/example/package.properties WEB-INF/classes/example/package_es.properties example/Login.jsp example/Menu.jsp example/Missing.jsp
[example.xml]
<action name="Login_*" method="{1}" class="example.Login"> <result name="input">/example/Login.jsp</result> <result type="redirect-action">Menu</result> </action> <action name="*" class="example.ExampleSupport"> <result>/example/{1}.jsp</result> </action>
Loing_xxxのアクションの場合、example.Loginのxxxメソッドが呼ばれる。で、xxxメソッドの返り値(String)が"input"であった場合、/example/Login.jspが呼び出され、返り値が"success"であった場合、Menu.actionにリダイレクトされる。との意だと思う。。。
actionタグのmethod属性は、省略すれば、method="execute"となり、execute()メソッドが実行される。
ちなみに、今回の"success"の場合、example.xmlには、name="Menu"のactionタグの定義がされてないので、結果的にname="*"のアクションが適用され、/example/Menu.jspが呼び出されることになる。
面白いのがmethodの"{1}"で、"*"に入る文字列がそこに入るもよう。つまり、アクションがLogin_inputであれば、
<action name="Login_input" method="input" class="example.Login">
と同じことになるっぽい。
resultタグのname属性が実行される返り値の文字列で、"success"は省略可になってる。type属性の"redirect-action"は、指定されたアクション(今回の場合はMenu.action)が再実行される。
type属性には、同アクションの別メソッドを呼び出す"method"、別アクションのexecute()を呼び出す"action"、別URLにリダイレクトする"redirect"があるっぽい。検証はまた今度。。。redirect-actionとredirectの違いがわからん。。。
[example.Login.java]
com.opensymphony.xwork2.ActionSupport △ | example.ExampleSupport △ | example.Login
リクエストの受け口で、継承関係はこんな感じ。
アクションがLogin_input.actionの場合、ActionSupport#input()メソッドが呼ばれる。アクションがLogin.actionの場合、Login#execute()メソッドが呼ばれる。
また、画面のチェック項目を記述した「アクション-validation.xml」といったファイル名のvalidationファイルを用意しておけば、勝手に入力項目チェックを行ってくれる。ただし、input()メソッドの場合はvalidationは実行されない。
Loginのアクションの場合、Login-validation.xmlに記述されたチェックが走り、チェックに引っかかった場合、
<result name="input">
タグで指定した/example/Login.jspが呼ばれる。
ちなみに特定のメソッドでvalidationを実行させたくない場合は、
@SkipValidation public String hoge() throws Exception { ... }
みたいに、@SkipValidationアノテーションを使うべしみたいなことを書いてあったけど、他に方法はないんだろうか。。。
[example/Login.jsp]
struts2では、
<%@ taglib prefix="s" uri="/struts-tags" %>
を記述することで、s:〜で始まるいろんなタグライブラリと使うことができる。
<s:form action="Login"> <s:textfield key="username" /> <s:password key="password" /> <s:submit/> </s:form>
<s:textfield ...>タグが<input type="text" ...>に対応し、 <s:password ...>タグが<input type="password" ...>に対応し、 <s:submit ...>タグが<input type="submit" ...>に対応する。 <s:textfield ...>タグでは、 <s:textfield name="hoge" label="ほげ">> と記述すれば、 <td><label for="xxx" class="label">ほげ:</label></td> <td><input type="text" name="hoge" value="" id="xxx" /></td> のようなHTMLが生成される。
key="hoge"のようにkey属性を使うと、生成されるHTMLでは、name属性が、name="hoge"となり、かつ、propertiesファイルから取得した内容をlabelタグの値として表示する。
画面上の入力値を取得するときは、ActionSupportの実装クラスにsetterを用意しておけばよし。Loginクラスの場合、usernameがsetUsernameでセットされ、passwordがsetPasswordでセットされる。
逆に画面にパラメータ値を渡すときは、
<s:textfield key="username" value="%{username}" />
のようにしておくと、getter(ここではgetUsername)で取得できる値が画面上にセットされる。
あー、思いつくままに書いただけだから、情報としてぐちゃぐちゃ。。。正しいかも分かんないし、余裕があれば整理したいけど、、、今余裕がない。。。