在S2Struts中生成一个可以使用注释的Validation,需要完成以下的处理。
我们将通过生成一个Validation来检验2个输入值是否相同的处理步骤中,对这一工作进行说明。
追加一个新的Struts(commons validator)的Validation,需要进行以下处理。
- 生成一个检验用的类
- 向validator-rules.xml文件中追加设定信息
在Struts Validator Guide资料里,有记载使用Struts追加一个新的Validation的方法,也可以作为参考。
检验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 MyFieldChecks {
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;
}
}
首先,取得用于检验的属性值。
其次,取得在validation设定中的"secondProperty"变量里指定的属性名,从而取得其值。
最后对2个值进行比较以便确认是否是正确的值。
在这里,关键的是必须有一个"secondProperty"变量。
这个变量,在生成Validation注释的时候声明为属性值。
然后将上述的类追加到validator-rules.xml文件中。
validator标签的name属性(validator name)里指定的内容,是注释名及其相关。
在S2Struts中,按以下的规则变换注释名,判断其是否和validator name相一致,从而取得其值。
- 注释名的开头字母为小写字母
- 注释名以"Type"结尾的场合则将"Type"除去
例如,Hoge注释的场合,validator name为"hoge",FooType注释的场合,validator name则为"foo"。
因为这回的注释名是TwoFields,所以name就是"twoFields"。在validator-rules.xml文件中追加以下的内容。
<validator name="twoFields"
classname="org.seasar.struts.examples.validator.MyFieldChecks"
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的过程。
生成Validation注释,需要进行以下的处理。
S2Struts可以提供的注释有3种,也即常量注释,Tiger注释,Backport175注释。
作为常量注释利用的场合,不必定义注释。
作为Tiger注释利用的场合,需要指定org.seasar.struts.validator.annotation.tiger.ValidatorTarget作为meta注释,按如下方法作成。
package org.seasar.struts.examples.validator.annotation.tiger;
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.tiger.ValidatorTarget;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@ValidatorTarget
public @interface TwoFields {
String secondProperty();
}
作为Backport175注释利用的场合,需要指定org.seasar.struts.validator.annotation.backport175.ValidatorTarget作为meta注释,按如下方法作成。
package org.seasar.struts.examples.validator.annotation.backport175;
/**
* @org.seasar.struts.validator.annotation.backport175.ValidatorTarget
*/
public interface TwoFields {
String secondProperty();
}
这回为了进行值的检验,需要指定secondProperty,所以如上述记载的那样。
在validation设定中如果不需要变量,就没必要定义属性,也没必要做成以下的ConfigRegister。
注释中取得的值,需要生成ConfigRegister类并作设定,因此生成一个TwoFieldsConfigRegisterImpl。
TwoFieldsConfigRegisterImpl类是org.seasar.struts.lessconfig.validator.config.ConfigRegister的实装类。
register方法的参数为field和parameter。
field是一个对象,在其内部,对字段进行妥当性检查以及生成错误信息时,拥有可以替换的妥当性检查名单和信息名及信息值。
也即收藏Validation内容的对象。
parameter是一个Map,以注释中定义的方法名为key,方法的返回值为value。
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.lessconfig.validator.config.ConfigRegister;
public class TwoFieldsConfigRegisterImpl implements ConfigRegister {
public void register(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"。
因为这回作为组件进行登记,生成一个新的validator.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,读取validator.dion的内容。
<include path="validator.dicon"/>
到此为止,是用S2Struts生成新的注释的过程。
至此,生成一个使用注释的Validation的过程就完成了。
为了验证生成的TwoFields注释,做以下的处理。
首先生成一个View。这里是把JSP用作一个View。这是为了确认结果简单做成的一个JSP。
<%@ page contentType="text/html;charset=Windows-31j" language="java" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://www.seasar.org/tags-s2struts" prefix="s2struts" %>
<html>
<head>
<title>Two Fields Test</title>
</head>
<body>
<html:errors />
<html:form action="/twoFields" method="POST">
<s2struts:page/>
<table>
<tr>
<td>field</td>
<td><html:text property="field"/></td>
</tr>
<tr>
<td>confirm field</td>
<td><html:text property="confirmField"/></td>
</tr>
</table>
<html:submit/>
</html:form>
</body>
</html>
然后生成一个Action。这回用的是无设定功能的POJO的Action(详细内容请参考「无设定S2Struts指南」)。
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";
}
}
虽然Action的处理仅仅是返回"success"值,但用于TwoFields注释的动作确认已经足够了。
Action作为组件需要登记。新生成的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 name="twoFieldsAction"
class="org.seasar.struts.examples.validator.TwoFieldsActionImpl"
instance="request" />
</components>
然后在app.dicon里追加include以读取twoFields.dicon。
<include path="org/seasar/struts/examples/dicon/twoFields.dicon"/>
最后生成Form。作为例子,以下记述了常量注释和Tiger注释时的2个Form。
请用所使用到的注释来生成Form。
package org.seasar.struts.examples.validator;
import java.io.Serializable;
public class TwoFieldsForm implements Serializable {
private static final long serialVersionUID = 1L;
private String field = "";
private String confirmField = "";
public String getField() {
return field;
}
public static final String field_VALIDATOR_0 = "required";
public static final String field_VALIDATOR_1 = "twoFields, secondProperty = confirmField";
public static final String field_VALIDATOR_ARGS = "Field, resource=false";
public void setField(String field) {
this.field = field;
}
public String getConfirmField() {
return confirmField;
}
public static final String confirmField_VALIDATOR = "required";
public static final String confirmField_VALIDATOR_ARGS = "ConfirmField, resource=false";
public void setConfirmField(String confirmField) {
this.confirmField = confirmField;
}
}
package org.seasar.struts.examples.validator;
import java.io.Serializable;
import org.seasar.struts.examples.validator.tiger.TwoFields;
import org.seasar.struts.validator.annotation.tiger.Args;
import org.seasar.struts.validator.annotation.tiger.Required;
public class TwoFieldsForm implements Serializable {
private static final long serialVersionUID = 1L;
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
@Args(keys = "ConfirmField", resource = false)
public void setConfirmField(String confirmField) {
this.confirmField = confirmField;
}
}
这样就可以进行确认了。
启动Tomcat,从浏览器访问http://localhost:8080/s2struts-example/pages/twoFields.jsp进行动作确认。
生成一个新的使用注释的Validation,与通常的处理相比,也许是一件很麻烦的事情,不过一旦完成的话,在Form中就很容易使用了。
如此说来,生成注释时的辛苦也有了足够的回报。
你是否愿意尝试做一个自己用的Validation呢?
|