2009年6月10日水曜日

Struts2.1を使ってみる。単純な入力フォームの例

単純に表示するだけは出来たので、入力フォームから入力するような機能を試してみます。
環境はすでに用意してあるものを使います。

1 アクションクラス作成。

net.ukauka.lab.action.test2にHello2Action.javaを作成します。
package net.ukauka.lab.action.test2;

import org.apache.struts2.convention.annotation.ParentPackage;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.EmailValidator;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;

@ParentPackage(value="default")

public class Hello2Action extends ActionSupport{

public String name;
public String email;

private static final long serialVersionUID = 1L;

public String execute() throws Exception {
return "input";
}

@Validations(requiredStrings=@RequiredStringValidator(fieldName="name",message="名前いれて"))
public String inputName() throws Exception {
return "ok";
}

@Validations(
requiredStrings=@RequiredStringValidator(fieldName="email",message="メールアドレスいれて"),
emails=@EmailValidator(fieldName="email",message="メールアドレスがおかしい")
)
public String inputEmail() throws Exception {
return "ok";
}

}

http://localhost:8080/app1/test2/hello2.action でアクセスします。

入力用にname,emailという変数をpublicで作成します。この変数に入力値が設定されます。
inputName,inputEmailというメソッドは入力実行時に呼び出されます。
今回は無意味に送信ボタンを二つ用意してそれぞれの動作がわかるようにしています。
@ParentPackage(value="default")
という記述は、どの設定を使用するかです。これを書いていないとデフォルトではstruts-defaultが使用されます。
後述のインターセプタ設定に関連するので必要です。

@Validations うんたらかんたらの部分はバリデーションの設定です。極力設定ファイルを書きたくないのでアノテーションで設定するようにしました。
メソッド毎に違うバリデーションを行いたいので、二つのメソッドで別のバリデーションを設定してあります。

2 jspを作成

入力用と表示用のビューを作成します。

入力用 test2/hello2-input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>入力</title>
<style>
.errorMessage {
color:red;
}
.errorLabel {
color:red;
}

</style>
</head>
<body>
<h1>入力</h1>
<s:form>
<s:textfield label="名前" name="name" />
<s:textfield label="メールアドレス" name="email" />

<s:submit value="名前入力" method="inputName" />
<s:submit value="メールアドレス入力" method="inputEmail" />
</s:form>
</body>
</html>

入力フォームはstrutsタグを使うと楽です。基本は

s:formの中に書く入力用タグを配置するだけです。

s:formを指定するだけで、入力欄とかサブミットボタンとかは勝手にtableタグで適当に整形されて表示されます。

これはthemeを指定することでいろいろ変更できるようです。とりあえず勝手に整形されるのは困るって場合は<s:form theme="simple'>を指定すればいいです。デフォルトはtheme=xhtmlらしいです。他にもcssレイアウトやajaxを使うものとかあるようですが、面倒なのでデフォルトでやっときます。

見たまんまですが、s:submitでmethodを指定してますがこれが実行したいメソッドの名前になります。

cssでerrorMessage、errorLabelを指定してますが、これはエラー時に出力されるメッセージ用です。色でも変えておかないとわかりづらいです。

出力用 test2/hello2-ok.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>出力</title>
</head>
<body>
<h1>出力</h1>
名前:${name}<br/>
メールアドレス:${email}
<a href="hello2.action">戻る</a>
</body>
</html>

3 設定ファイル
<?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>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />

<package name="default" extends="struts-default">
<interceptors>
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception" />
<interceptor-ref name="alias" />
<interceptor-ref name="servletConfig" />
<interceptor-ref name="i18n" />
<interceptor-ref name="prepare" />
<interceptor-ref name="chain" />
<interceptor-ref name="debugging" />
<interceptor-ref name="profiling" />
<interceptor-ref name="scopedModelDriven" />
<interceptor-ref name="modelDriven" />
<interceptor-ref name="fileUpload" />
<interceptor-ref name="checkbox" />
<interceptor-ref name="staticParams" />
<interceptor-ref name="actionMappingParams" />
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
<param name="validateAnnotatedMethodOnly">true</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
</package>
</struts>

今回この設定を調べるのに結構時間食いましたw
アノテーションでメソッド毎にバリデーションを実行するのに、

<interceptor-ref name="validation">
<param name="validateAnnotatedMethodOnly">true</param>
</interceptor-ref>

validateAnnotatedMethodOnlyをtrueに設定する必要があるんですが、この方法がよくわかんなかったのです。

まぁ、わかってみると簡単なんですが、struts-defaultを継承したpackageを作成しinterceptor-stackのdefaultStackを上書きすればよかったです。

で、ここで指定しているpackageをアクションクラス側で指定しないとデフォルトのstruts-defaultが使用されてうまくいきません。(結構悩みました)

defaultStackはstruts-defaultの内容をそのままコピーしてもってきてvalidation部分だけ追加しました。いらなそうなインターセプターは削除しておいてもいいと思います。

4 実行

http://localhost:8080/app1/test2/hello2.action にアクセスすると入力画面が表示されます。
「名前入力」ボタンを押すと、名前欄のみチェックされて、問題なければ出力画面が表示されます。

「メールアドレス入力」も同様です。

二つのボタンで別々のバリデーションが働きます。

hello2Action#execute 実行

test2/hello2-input.jsp 表示

hello2Action#inputName 実行

test2/hello2-ok.jsp 表示

という流れになります。

0 件のコメント:

コメントを投稿