S2Struts1.2.0-EA4での新規Validationの追加
ここで書くべきことじゃないけど、ないよりかあったほうが良いと思ったので。
S2Struts1.2.0-EA4ではアノテーションを利用してValidationを設定できます。
新規のValidationを追加するにはアノテーションを作成する等の作業を行う必要があります。
Maxbytelength、MinbytelengthアノテーションはS2Struts独自のValidationですので、新規Validation作成の参考になります。
S2StrutsExample1.2.0-EA4に2つの入力内容が同じか検証するValidationを追加する作業を通して、新規Validationの追加方法を説明します。
Struts Validator Guide(http://struts.apache.org/userGuide/dev_validator.html)に、Strutsでの新規Validationを追加する方法が記述されています。こちらも参考にしてください。
Struts(commons validator)での作業
Struts(commons validator)としての新規Validationを追加するには、
- 検証用クラスの作成
- validator-rules.xmlへ設定情報の追加
を行います。
2つの入力内容が同じか検証するクラスは以下のようになります。
package org.seasar.struts.examples.validator; import javax.servlet.http.HttpServletRequest; import org.apache.commons.validator.Field; import org.apache.commons.validator.GenericValidator; import org.apache.commons.validator.Validator; import org.apache.commons.validator.ValidatorAction; import org.apache.commons.validator.util.ValidatorUtils; import org.apache.struts.action.ActionMessages; import org.apache.struts.validator.Resources; public class FieldChecks { public static boolean validateTwoFields(Object bean, ValidatorAction validatorAction, Field field, ActionMessages errors, Validator validator, HttpServletRequest request) { String value = ValidatorUtils.getValueAsString(bean, field.getProperty()); String sProperty2 = field.getVarValue("secondProperty"); String value2 = ValidatorUtils.getValueAsString(bean, sProperty2); if (!GenericValidator.isBlankOrNull(value)) { try { if (!value.equals(value2)) { errors.add(field.getKey(), Resources.getActionMessage( validator, request, validatorAction, field)); return false; } } catch (Exception e) { errors.add(field.getKey(), Resources.getActionMessage( validator, request, validatorAction, field)); return false; } } return true; } }
次に上記のクラスをvalidator-rules.xmlに追加します。
validatorタグのname属性(validator name)に指定する内容は、アノテーション名と関連があります。
S2Strutsでは以下の規則によりアノテーション名を変換しvalidator nameと一致するか判断して特定しています。
例えば、Hogeアノテーションの場合のvalidator nameは"hoge"となり、FooTypeアノテーションの場合のvalidator nameは"foo"となります。
今回はアノテーション名をTwoFieldsとするためnameは"twoFields"とします。
validator-rules.xml
<validator name="twoFields" classname="org.seasar.struts.examples.validator.FieldChecks" method="validateTwoFields" methodParams="java.lang.Object, org.apache.commons.validator.ValidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.ActionMessages, org.apache.commons.validator.Validator, javax.servlet.http.HttpServletRequest" depends="" msg="errors.twoFields"/>
msg属性に"errors.twoFields"と指定したので、このメッセージKeyをapplication.propertiesに追加します。
errors.twoFields={0} has to have the same value as the confirm field.
ここまでがStrutsでの新規Validation追加作業です。
S2Strutsでの作業
S2Strutsに新規Validationを追加する場合は、
- アノテーションの定義
- ConfigRegisterの作成
を行う必要があります。
Valiadtionのアノテーションにはメタアノテーションとしてorg.seasar.struts.validator.annotation.ValidatorTargetを指定します。
TwoFieldsアノテーションは以下のようになります。
package org.seasar.struts.examples.validator.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.seasar.struts.validator.annotation.ValidatorTarget; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @ValidatorTarget public @interface TwoFields { String secondProperty(); }
次に上記アノテーションを登録するためのConfigRegisterとしてTwoFieldsConfigRegisterImplを作成します。
TwoFieldsConfigRegisterImplは、org.seasar.struts.validator.config.ConfigRegisterを実装します。
registメソッドの引数はfieldとparameterです。
parameterは、アノテーションで定義したメソッド名をkey、メソッドの戻り値をvalueとしたMapです。
package org.seasar.struts.examples.validator.config; import java.util.Map; import org.apache.commons.validator.Field; import org.apache.commons.validator.Var; import org.seasar.struts.validator.config.ConfigRegister; public class TwoFieldsConfigRegisterImpl implements ConfigRegister { public void regist(Field field, Map parameter) { String secondProperty = (String) parameter.get("secondProperty"); Var var = new Var(); var.setName("secondProperty"); var.setValue(secondProperty); field.addVar(var); } }
ConfigRegisterはコンポーネントとして登録する必要があります。
登録するときのコンポーネント名は、validator nameのときと同様のアノテーション名変換を行い"ConfigRegister"を付け加えた名前となります。
例えば、Hogeアノテーションの場合は"hogeConfigRegister"となり、FooTypeアノテーションの場合は"fooConfigRegister"となります。
今回はコンポーネントとして登録するために新規でallvalidator.dionを作成します。
<?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <component name="twoFieldsConfigRegister" class="org.seasar.struts.examples.validator.config.TwoFieldsConfigRegisterImpl"/> </components>
そしてapp.diconにincludeを追加して、allvalidator.dionを読み込むようにします。
<include path="org/seasar/struts/examples/dicon/allvalidator.dicon"/>
これで新規Validation追加作業は終了です。
動作確認
今回作成したTwoFieldsアノテーションを試すには、
を行う必要があります。
まずActionの作成ですが、今回はPOJOのActionで無設定機能をフルに使います。
Actionのインターフェースと実装は以下のようになります。
package org.seasar.struts.examples.validator; public interface TwoFieldsAction { String execute(); }
package org.seasar.struts.examples.validator; public class TwoFieldsActionImpl implements TwoFieldsAction { public String execute() { return "success"; } }
無設定機能をフルに利用するので、StrutsActionアノテーション、StrutsActionForwardアノテーションは不要です。
Actionの処理は"success"を返すだけですがTwoFieldsアノテーションの動作確認には十分です。
Actionはコンポーネントとして登録する必要があります。
S2.3の自動登録機能を利用すれば毎回diconファイルを作る必要はなくなるのですが、S2StrutsExampleがまだ対応していないので、個別に登録することにします。。。
新規に作成したtwoFields.diconは以下のようになります。
<?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <component class="org.seasar.struts.examples.validator.TwoFieldsActionImpl" /> </components>
そしてapp.diconにincludeを追加して、twoFields.diconを読み込むようにします。
<include path="org/seasar/struts/examples/dicon/twoFields.dicon"/>
次はForm(Dto)を作成します。
package org.seasar.struts.examples.validator; import java.io.Serializable; import org.seasar.struts.examples.validator.annotation.TwoFields; import org.seasar.struts.validator.annotation.Args; import org.seasar.struts.validator.annotation.Required; public class TwoFieldsDto implements Serializable { private String field = ""; private String confirmField = ""; public String getField() { return field; } @Required @TwoFields(secondProperty="confirmField") @Args(keys = "Field", resource = false) public void setField(String field) { this.field = field; } public String getConfirmField() { return confirmField; } @Required public void setConfirmField(String confirmField) { this.confirmField = confirmField; } }
Form(Dto)も無設定機能をフルに利用しますので、StrutsActionFormアノテーションは不要ですが、Validation関連のアノテーションを指定するのを忘れないようにしましょう。
最後にJSPを作成します。
TwoFieldsActionに自動的にforward設定されるようにするため、JSP名はtwoFields.jspとしてpagesディレクトリに作成します。
<%@ page contentType="text/html;charset=Windows-31j" language="java" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %> <%@ taglib uri="http://www.seasar.org/tags-s2struts" prefix="s2struts" %> <tiles:insert page="/pages/layout/layout.jsp"> <tiles:put name="layoutTitle" type="string"> Two Fields Check </tiles:put> <tiles:put name="body" type="string"> <html:errors /> <html:form action="/twoFields" method="POST"> <s2struts:page/> <table> <tr> <td>field</td> <td><html:text property="field" styleClass="text" errorStyleClass="text-error"/></td> </tr> <tr> <td>confirm field</td> <td><html:text property="confirmField" styleClass="text" errorStyleClass="text-error"/></td> </tr> </table> <html:submit/> </html:form> </tiles:put> </tiles:insert>
ここでのポイントはs2struts:pageタグを利用しているところです。
これにより、TwoFieldsActionでinputを指定していなくても検証エラーのときにこのJSPを再表示します。
これで動作確認する準備ができました。
Tomcatを起動して、
http://localhost:8080/s2struts-example/pages/twoFields.jsp
にアクセスし、動作を確認してください。
新規のValidationを追加する作業はちょっと大変ですが、一度追加すれば簡単にForm(Dto)で使えるようになると思います。