【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】 ​

1 编写校验规则文件

<s:fielderror/>
<s:form action="regist">
<s:textfield name="name" label="用户名"/>
<s:textfield name="pass" label="密码"/>
<s:textfield name="age" label="年龄"/>
<s:textfield name="birth" label="生日"/>
<s:submit value="注册"/>
</s:form>

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring

输入校验文件

<?xml version="1.0" encoding="GBK"?>
<!-- 指定校验配置文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.3//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<!-- 校验文件的根元素 -->
<validators>
<!-- 校验Action的name属性 -->
<field name="name">
<!-- 指定name属性必须满足必填规则 -->
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>必须输入名字</message>
</field-validator>
<!-- 指定name属性必须匹配正则表达式 -->
<field-validator type="regex">
<param name="expression"><![CDATA[(\w{4,25})]]></param>
<message>您输入的用户名只能是字母和数字
,且长度必须在4到25之间</message>
</field-validator>
</field>
<!-- 校验Action的pass属性 -->
<field name="pass">
<!-- 指定pass属性必须满足必填规则 -->
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>必须输入密码</message>
</field-validator>
<!-- 指定pass属性必须满足匹配指定的正则表达式 -->
<field-validator type="regex">
<param name="expression"><![CDATA[(\w{4,25})]]></param>
<message>您输入的密码只能是字母和数字
,且长度必须在4到25之间</message>
</field-validator>
</field>
<!-- 指定age属性必须在指定范围内-->
<field name="age">
<field-validator type="int">
<param name="min">1</param>
<param name="max">150</param>
<message>年纪必须在1到150之间</message>
</field-validator>
</field>
<!-- 指定birth属性必须在指定范围内-->
<field name="birth">
<field-validator type="date">
<!-- 下面指定日期字符串时,必须使用本Locale的日期格式 -->
<param name="min">1900-01-01</param>
<param name="max">2050-02-21</param>
<message>生日必须在${min}到${max}之间</message>
</field-validator>
</field>
</validators>

Struts 2 中每一个 Action 都有一个校验文件。
文件名命名格式:

<Action-validation.xml

该文件应该保存在与 Action class 文件相同的路径下。
输入校验失败后,Struts 2 自动返回名为 “input” 的 Result。

<!-- 用户注册的Action -->
<action name="regist" class="org.crazyit.app.action.RegistAction">
<!-- 类型转换失败、输入校验失败,转入该页面 -->
<result name="input">/regist.jsp</result>
<result>/show.jsp</result>
</action>

2 国际化提示信息

为 message 元素指定 key 属性, key 属性指定是国际化提示信息对应的 key 。

...
<!-- 校验Action的name属性 -->
<field name="name">
<!-- 指定name属性必须满足必填规则 -->
<field-validator type="requiredstring">
<param name="trim">true</param>
<message key="name.requried"/>
</field-validator>
<!-- 指定name属性必须匹配正则表达式 -->
<field-validator type="regex">
<param name="expression"><![CDATA[(\w{4,25})]]></param>
<message key="name.regex"/>
</field-validator>
</field>

国际化资源文件 mess.properties 中增加对应的 key 。

xwork.default.invalid.fieldvalue={0}字段无效
name.requried=您必须输入用户名!
name.regex=您输入的用户名只能是字母和数组,且长度必须在4到25之间!
pass.requried=您必须输入密码!
pass.regex=您输入的密码只能是字母和数组,且长度必须在4到25之间!
age.range=您的年龄必须在${min}和${max}之间!
birth.range=您的生日必须在${min}和${max}之间!

3 使用客户端校验

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring_02

<s:fielderror/>
<s:form action="regist" validate="true">
<s:textfield name="name" label="用户名"/>
<s:textfield name="pass" label="密码"/>
<s:textfield name="age" label="年龄"/>
<s:textfield name="birth" label="生日"/>
<s:submit value="注册"/>
</s:form>

但是运行时出错。

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_03

<!-- 可以匹配任何请求,直接转向对应的页面
例如abc请求,那么就会跳转到/WEB-INF/content/abc.jsp -->
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_04

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring_05


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_校验器_06

4 字段校验器配置风格

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_struts2.0_07

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring_08

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_struts2.0_09

5 非字段校验器配置风格

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_10

使用非字段校验器风格改写前面的校验规则文件。

<?xml version="1.0" encoding="GBK"?>
<!-- 指定Struts 2数据校验的规则文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.3//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<!-- Struts 2校验文件的根元素 -->
<validators>
<!-- 配置指定必填字符串的校验器 -->
<validator type="requiredstring">
<!-- 使用该校验器校验name属性 -->
<param name="fieldName">name</param>
<param name="trim">true</param>
<!-- 指定校验失败后输出name.required对应的国际化信息 -->
<message key="name.requried"/>
</validator>
<!-- 配置指定正则表达式的校验器 -->
<validator type="regex">
<!-- 使用该校验器校验name属性 -->
<param name="fieldName">name</param>
<param name="trim">true</param>
<param name="expression"><![CDATA[(\w{4,25})]]></param>
<!-- 指定校验失败后输出name.required对应的国际化信息 -->
<message key="name.regex"/>
</validator>
<!-- 配置指定必填字符串的校验器 -->
<validator type="requiredstring">
<!-- 使用该校验器校验pass属性 -->
<param name="fieldName">pass</param>
<param name="trim">true</param>
<!-- 指定校验失败后输出pass.required对应的国际化信息 -->
<message key="pass.requried"/>
</validator>
<!-- 配置指定正则表达式的校验器 -->
<validator type="regex">
<!-- 使用该校验器校验pass属性 -->
<param name="fieldName">pass</param>
<param name="trim">true</param>
<param name="expression"><![CDATA[(\w{4,25})]]></param>
<!-- 指定校验失败后输出pass.required对应的国际化信息 -->
<message key="pass.regex"/>
</validator>
<!-- 配置指定整数校验器 -->
<validator type="int">
<!-- 使用该校验器校验age属性 -->
<param name="fieldName">age</param>
<!-- 指定整数校验器的范围-->
<param name="min">1</param>
<param name="max">150</param>
<!-- 指定校验失败后输出age.range对应的国际化信息 -->
<message key="age.range"/>
</validator>
<!-- 配置指定日期校验器 -->
<validator type="date">
<!-- 使用该校验器校验birth属性 -->
<param name="fieldName">birth</param>
<!-- 指定日期校验器的范围-->
<param name="min">1900-01-01</param>
<param name="max">2050-02-21</param>
<!-- 指定校验失败后输出birth.range对应的国际化信息 -->
<message key="birth.range"/>
</validator>
</validators>

6 短路校验器

前面校验提示信息输入两行

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_struts2.0_11

很不友好,我们需要输出第一行提示信息

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring_12

7 校验文件的搜索规则

Struts 2 允许通过为校验规则文件名添加 Action 别名来指定具体需要校验的处理逻辑。

<ActionClassName>-<ActionAliasName>-validation.xml

例如 为 loginPro 逻辑 Action 单独指定校验规则,则校验文件的文件名为 RegistAction-loginPro-validation.xml 。

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_struts2.0_13

8 校验顺序和短路

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring_14

9 内建校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_15

<validators>
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
<validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
<validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
<validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
</validators>

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_校验器_16

9-1 必填校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_17

9-2 必填字符串校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_struts2.0_18

9-3 整数校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_19


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_20

9-4 日期校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_校验器_21

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_22

9-5 表达式校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_23

9-6 字段表达式校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_struts2.0_24

9-7 邮件地址校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_25


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_校验器_26


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_27

9-8 网址校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_28


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_校验器_29

9-9 Visitor 校验器

Visitor 校验器主要用于检测 Action 里的复合属性,例如一个 Action 里包含了 User 类型的 属性。

RegistAction-validation.xml

<!-- 校验规则文件的根元素 -->
<validators>
<!-- 指定校验user字段 -->
<field name="user">
<!-- 使用Visitor校验器 -->
<field-validator type="visitor">
<!-- 指定校验规则文件的context -->
<param name="context">userContext</param>
<!-- 指定校验失败后提示信息是否添加下面前缀 -->
<param name="appendPrefix">true</param>
<!-- 指定校验失败的提示信息前缀 -->
<message>用户的:</message>
</field-validator>
</field>
</validators>

User-userContext-validation.xml (与 User.class 同路径下)

<?xml version="1.0" encoding="GBK"?>
<!-- 指定校验配置文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.3//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<!-- 校验文件的根元素 -->
<validators>
<!-- 校验User属性的name属性 -->
<field name="name">
<!-- 指定name属性必须满足必填规则 -->
<field-validator type="requiredstring">
<param name="trim">true</param>
<!-- 如果校验失败,输出name.requried对应的国际化信息 -->
<message key="name.requried"/>
</field-validator>
<!-- 指定name属性必须匹配正则表达式 -->
<field-validator type="regex">
<param name="expression"><![CDATA[(\w{4,25})]]></param>
<!-- 如果校验失败,输出name.regex对应的国际化信息 -->
<message key="name.regex"/>
</field-validator>
</field>
<!-- 校验User属性的pass属性 -->
<field name="pass">
<!-- 指定pass属性必须满足必填规则 -->
<field-validator type="requiredstring">
<param name="trim">true</param>
<!-- 如果校验失败,输出pass.requried对应的国际化信息 -->
<message key="pass.requried"/>
</field-validator>
<!-- 指定pass属性必须满足匹配指定的正则表达式 -->
<field-validator type="regex">
<param name="expression"><![CDATA[(\w{4,25})]]></param>
<!-- 如果校验失败,输出pass.regex对应的国际化信息 -->
<message key="pass.regex"/>
</field-validator>
</field>
<!-- 指定User属性的age属性必须在指定范围内-->
<field name="age">
<field-validator type="int">
<param name="min">1</param>
<param name="max">150</param>
<!-- 如果校验失败,输出age.range对应的国际化信息 -->
<message key="age.range"/>
</field-validator>
</field>
<!-- 指定User属性的birth属性必须在指定范围内-->
<field name="birth">
<field-validator type="date">
<!-- 下面指定日期字符串时,必须使用本Locale的日期格式 -->
<param name="min">1900-01-01</param>
<param name="max">2050-02-21</param>
<!-- 如果校验失败,输出birth.range对应的国际化信息 -->
<message key="birth.range"/>
</field-validator>
</field>
</validators>

修改 regist.jsp

<s:form action="registPro">
<s:textfield name="user.name" label="用户名"/>
<s:textfield name="user.pass" label="密码"/>
<s:textfield name="user.age" label="年龄"/>
<s:textfield name="user.birth" label="生日"/>
<s:submit value="注册"/>
</s:form>

9-10 转换校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_校验器_30


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring_31

9-11 字符串长度校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_32


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_java_33

9-12 正则表达式校验器

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_spring_34

10 基于 Annotation 的输入校验

为了在 Action 类通过 Annotation 指定验证规则,经过如下配置即可:
使用验证器 Annotation 修饰 Action 里各属性对应的 setter 方法。

public class RegistAction extends ActionSupport
private String name;
private String pass;
private int age;
private Date birth;

//name属性的setter和getter方法
//使用Annotation指定必填、正则表达式两个校验规则
@RequiredStringValidator(key = "name.requried"
, message = "")
@RegexFieldValidator(expression = "\\w{4,25}"
,key = "name.regex" , message = "")
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}

//pass属性的setter和getter方法
@RequiredStringValidator(key = "pass.requried"
,message = "")
@RegexFieldValidator(expression = "\\w{4,25}"
,key = "pass.regex" ,message = "")
public void setPass(String pass)
{
this.pass = pass;
}
public String getPass()
{
return this.pass;
}

//age属性的setter和getter方法
@IntRangeFieldValidator(message = ""
, key = "age.range", min = "1"
, max = "150")
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}

//birth属性的setter和getter方法
//使用Annotation指定日期范围校验规则
@DateRangeFieldValidator(message = ""
, key = "birth.range", min = "1900/01/01"
, max = "2050/01/21")
public void setBirth(Date birth)
{
this.birth = birth;
}
public Date getBirth()
{
return this.birth;
}
}

11 手动完成输入校验

11-1 重写 validate() 方法

public class RegistAction extends ActionSupport
private String name;
private String pass;
private int age;
private Date birth;
...
public void validate()
{
System.out.println("进入validate方法进行校验"
+ name);
//要求用户名必须包含crazyit子串
if(!name.contains("crazyit"))
{
addFieldError("user" ,
"您的用户名必须包含crazyit!");
}
}
}

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_35

11-2 重写 validateXxx() 方法

public class RegistAction extends ActionSupport
private String name;
private String pass;
private int age;
private Date birth;
...
public void validate()
{
System.out.println("进入validate方法进行校验" + name == null);
//要求用户名必须包含crazyit子串
if(!name.contains("crazyit"))
{
addFieldError("user" ,
"您的用户名必须包含crazyit!");
}
}
public void validateRegist()
{
System.out.println("进入validateRegist方法进行校验"
+ name);
//要求用户名必须包含.org子串
if(!name.contains(".org"))
{
addFieldError("user" ,
"您的用户名必须包含.org!");
}
}
}

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_36

<struts>
<!-- 指定Struts 2应用的国际化资源文件 -->
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 指定Struts 2应用编码的字符集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 定义处理用户请求的regist Action,使用.RegistAction的regist
方法处理用户请求 -->
<action name="registPro" class="org.crazyit.app.action.RegistAction"
method="regist">
<result name="input">/WEB-INF/content/regist.jsp</result>
<result>/WEB-INF/content/show.jsp</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_struts2.0_37

Struts 2 输入校验的步骤

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_hibernate_38


【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【输入校验】_校验器_39