【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>
输入校验文件
<?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 使用客户端校验
<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>
但是运行时出错。
<!-- 可以匹配任何请求,直接转向对应的页面
例如abc请求,那么就会跳转到/WEB-INF/content/abc.jsp -->
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
4 字段校验器配置风格
5 非字段校验器配置风格
使用非字段校验器风格改写前面的校验规则文件。
<?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 短路校验器
前面校验提示信息输入两行
很不友好,我们需要输出第一行提示信息
7 校验文件的搜索规则
Struts 2 允许通过为校验规则文件名添加 Action 别名来指定具体需要校验的处理逻辑。
<ActionClassName>-<ActionAliasName>-validation.xml
例如 为 loginPro 逻辑 Action 单独指定校验规则,则校验文件的文件名为 RegistAction-loginPro-validation.xml 。
8 校验顺序和短路
9 内建校验器
<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>
9-1 必填校验器
9-2 必填字符串校验器
9-3 整数校验器
9-4 日期校验器
9-5 表达式校验器
9-6 字段表达式校验器
9-7 邮件地址校验器
9-8 网址校验器
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 转换校验器
9-11 字符串长度校验器
9-12 正则表达式校验器
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!");
}
}
}
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!");
}
}
}
<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>
Struts 2 输入校验的步骤