read-AppFuse-14-实践-建立Action
● 根据AppFuse的帮助,实做Action
● 为Person POJO添加XDoclet tags
@struts.form include-all="true" extends="BaseForm"
AppFuse的Struts使用到了validator框架实现用户输入验证。
Ø Validator框架学习
将校验规则代码集中到外部的且对具体的应用程序中立的.xml文件中,将校验逻
辑从应用程序中分离出来,并且错误信息可以实现本地化,
(1) Validators:是Validator框架调用的一个Java类,它处理那些基本的通
用的校验,包括required、mask(匹配正则表达式)、最小长度、最大长
度、范围、日期等
(2)主要的两个配置文件:一个是validator-rules.xml,另一个是validation.xml。前者的内容主要包含一些校验规则,后者则包含需要校验的一些form及其组件的集合。
Ø validator-rules.xml:
validator-rules.xml文件定义应用程序可以使用的Validator。
validator-rules.xml充当模板的作用,定义所有应用程序可能要用到的
Validator。可以直接拷贝使用,其中的校验规则如下[引用]:
验证器名称
功能
required
验证一个必须填写的字段是否填写
mask
通过一个常规的 Jakarta RegExp 表达式检查字段值。要了解更多关于 RegExp 的信息,请参见 Jakarta RegExp 页。例如:
^[a-zA-Z]*$ 表示该值必须只包含字母
^\d{5}\d*$ 表示该值必须是五位数字
range
检查该值是否在指定范围内。
date
检查该值是否为一个有效值。它还能确保以期望的格式提供该数据,例如 MM/DD/YYYY 或 DD-MM-YYYY。
验证该值是以有效的电子邮件地址的格式提供。
creditCard
确认该值是一个有效的信用卡号码。
validator-rules.xml 中的msg属性用一个键值指定一个资源绑定,框架将用它来生
成正确的错误信息。资源绑定的使用有益于错误信息的本地化。
Ø validation.xml
validation.xml用于把你在validator-rules.xml中定义的各个Validator和你的应用程序中
的组件映射起来。
<form-validation>
<global>
<constant>
<constant-name>phone</constant-name>
<constant-value>^\(?(\d{3})\)?[-| ]?(\d{3})[-| ]?(\d{4})$</constant-value>
</constant>
<constant>
<constant-name>zip</constant-name>
<constant-value>^\d{5}\d*$</constant-value>
</constant>
<constant>
<constant-name>currency</constant-name>
<constant-value>^\d{1,3}(,?\d{1,3})*\.?(\d{1,2})?$</constant-value>
</constant>
</global>
<formset>
<!—jsp页面对应的form是struts-config.xml中定义的addressForm -->
<!—该页面有以下字段:city 、province 、country和postalCode -->
<form name=" ">
<!-- city 字段需要用户输入-->
<field property="city"
depends="required">
<!-- arg0 是当错误消息产生时传递给验证器的参数,参数的键在资源文件中有一个映射。-->
<!-- ApplicationResources_zh_CN.properties 中:userForm.addressForm.city=城市-->
<!-- ApplicationResources_zh_CN.properties 中:errors.required='{0}' errors.required-->
<!—验证不通过后的提示信息样例:”’城市’errors.required”-->
<arg0 key="addressForm.city"/>
</field>
<field property="province"
depends="required">
<arg0 key="addressForm.province"/>
</field>
<field property="country"
depends="required">
<arg0 key="addressForm.country"/>
</field>
<field property="postalCode"
depends="required,mask">
<msg
name="mask"
key="errors.zip"/>
<arg0 key="addressForm.postalCode"/>
<var>
<var-name>mask</var-name>
<var-value>${zip}</var-value>
</var>
</field>
</form>
… …
</formset>
</form-validation>
(3)Struts-config.xml中的配置
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,
/WEB-INF/validator-rules-custom.xml,
/WEB-INF/validation.xml"/>
</plug-in>
(4)ValidatorForm定义
为了使用服务器端验证, Action Form 实现类应该扩展 ValidatorForm 而不是
ActionForm 。当提交表单时,会执行 ValidatorForm 中的 validate() 方法,它将根
据 validation-rules.xml 和 validation.xml 文件进行验证。
AppFuse中的Form Bean继承了BaseForm,而BaseForm又继承了ValidatorForm
类,实现用户输入验证。
public class BaseForm extends ValidatorForm implements Serializable {
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
String parameter = mapping.getParameter();
if (parameter != null) {
String method = request.getParameter(parameter);
MessageResources resources =
(MessageResources) request.getAttribute(Globals.MESSAGES_KEY);
String cancel = resources.getMessage("button.cancel");
String delete = resources.getMessage("button.delete");
//如果用户选择表单’cancel’或者’delete’,则跳过表单验证。
if ((method != null) &&
(method.equalsIgnoreCase(cancel) ||
method.equalsIgnoreCase(delete))) {
return null;
}
return super.validate(mapping, request);
}
BaseForm中使用到了apache的commons包功能。
Ø org.apache.commons.lang学习
Commons-lang是jakarta对java.lang.*的加强功能的实现。
(1)org.apache.commons.lang.*: 提高了ArrayUtils, BooleanUtils,
CharSetUtils, ClassUtils, NumberUtils, ObjectUtils, StringUtils,
SystemUtils等Utils增强了java.lang.*的部分功能。如:
使用StringUtils.defaultString(request.getParameter("xxx")) 确保
request所取不为null,非常实用。
(2)org.apache.commons.lang.builder
Ø CompareToBuilder加强了Comparable.compareTo(Object)方法
传统的compareTo方法:
public class MyClass {
String field1;
int field2;
boolean field3;
...
public int compareTo(Object o) {
MyClass myClass = (MyClass) o;
return new CompareToBuilder()
.appendSuper(super.compareTo(o)
.append(this.field1, myClass.field1)
.append(this.field2, myClass.field2)
.append(this.field3, myClass.field3)
.toComparison();
}
}
org.apache.commons.lang.builder中的compareTo方法。
public int compareTo(Object o) {
return CompareToBuilder.reflectionCompare(this, o);
}
诸如这样的增强方法在org.apache.commons.lang中非常的多,使用起来简单实
用。如AppFuse中的使用,可以在以后开发中直接作为模板使用。
Ø org.apache.commons.lang.builder在AppFuse中的使用
public String toString() {
return ToStringBuilder.reflectionToString(this,
ToStringStyle.MULTI_LINE_STYLE);
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
注:ActionForm类其实是一个类似JavaBean一样的类,在Struts中用于捕捉用户输入并帮助传输这些输入到下一级应用程序组件。ActionForm也提供了在用户输入被传到业务逻辑层之前验证这些输入的便利场所[引用]。