简单的数据验证及自定义验证规则
方法一: 此方法是在Action的execute()方法中使用super.addFieldError("user.name", "姓名不能为空 !");
将验证过后的错误信息保存下来(查源码知道, 保存在Map<List(User)>中), 然后转发到页面进行验证展示.
此方法的缺点: Action中的代码量会大大增加!
具体实现: 为空验证
UserAction.java:
// 为空验证
if (user.getName() == null || "".equals(user.getName())) {
super.addFieldError("user.name", "姓名不能为空 !");
flag = false;
}
if (user.getAge() == null) {
super.addFieldError("user.age", "年龄不能为空 !");
flag = false;
}
if (user.getSalary() == null) {
super.addFieldError("user.salary", "工资不能为空 !");
flag = false;
}
if (user.getDate() == null) {
super.addFieldError("user.date", "生日不能为空 !");
flag = false;
}
struts.xml:
package name="user" namespace="/" extends="struts-default">
<action name="user" class="org.lxh.struts2demo.action.UserAction">
<result>user_show.jsp</result>
<result name="input">user_insert.jsp</result>
</action>
</package>
user_insert.jsp:
<!--
说明: value="<s:property value="user.name" />", 添加这个是为了在验证为空过后保留用户输入的信息
<s:property value="fieldErrors['user.name'][0]" />, 这个是验证的错误信息展示
-->
<form action="user.action" method="post">
姓名: <input type="text" name="user.name" value="<s:property value="user.name" />" /> <s:property value="fieldErrors['user.name'][0]" /><br>
年龄: <input type="text" name="user.age" value="<s:property value="user.age" />" /> <s:property value="fieldErrors['user.age'][0]" /><br>
工资: <input type="text" name="user.salary" value="<s:property value="user.salary" />" /> <s:property value="fieldErrors['user.salary'][0]" /><br>
生日: <input type="text" name="user.date" value="<s:property value="user.date" />" /> <s:property value="fieldErrors['user.date'][0]" /><br><br>
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</form>
测试:
方法二: 使用struts2框架提供的validate()方法进行验证
此方法是针对在接收数据之后进行验证, 而如果想要在接收数据之前进行验证, 就使用验证框架进行验证(见方法三).
在Action中重写validate()方法:
// 不需要判断标识flag, 此方法一旦发现有错误, 就自动跳转到到input所映射的路径中去,
// 如果没有错误, 那么就执行return ActionSupport.SUCCESS;
@Override
public void validate() {
// 为空验证
if (user.getName() == null || "".equals(user.getName())) {
super.addFieldError("user.name", "姓名不能为空 !");
}
if (user.getAge() == null) {
super.addFieldError("user.age", "年龄不能为空 !");
}
if (user.getSalary() == null) {
super.addFieldError("user.salary", "工资不能为空 !");
}
if (user.getDate() == null) {
super.addFieldError("user.date", "生日不能为空 !");
}
super.validate();
}
@Override
public String execute() throws Exception {
// 根据flag结果跳转, 这里的代码量变少
return ActionSupport.SUCCESS;
}
测试:
方法三: 使用struts2的框架规则进行验证操作
从struts2的jar包: \apps\struts2-portlet-2.1.8.1.war\WEB-INF\classes
中找到validators.xml文件, 此文件是struts2的框架验证规则,
validators.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<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="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"/>
</validators>
此时UserAction.java中不需要validate()方法, UserAction.java:
@SuppressWarnings("serial")
public class UserAction extends ActionSupport {
private User user = new User();
@Override
public String execute() throws Exception {
// 根据flag结果跳转
return ActionSupport.SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
在与UserAction.java同级包下创建: UserAction-validation.xml
找到\apps\struts2-portlet-2.1.8.1.war\WEB-INF\classes\org\apache\struts2\portlet\example目录下
的FormExample-formExamplePrg-validation.xml文件, 拷贝如下内容:
<field name="firstName">
<field-validator type="requiredstring">
<message>You must enter a first name</message>
</field-validator>
</field>
进行修改: 修改之后的UserAction-validation.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<validators>
<field name="user.name">
<field-validator type="requiredstring">
<message>姓名不允许为空!</message>
</field-validator>
</field>
<field name="user.age">
<field-validator type="requiredstring">
<message>年龄不允许为空!</message>
</field-validator>
<field-validator type="int">
<message>年龄必须是整数!</message>
</field-validator>
</field>
<field name="user.salary">
<field-validator type="requiredstring">
<message>工资不允许为空!</message>
</field-validator>
<field-validator type="double">
<message>工资必须是数字!</message>
</field-validator>
</field>
<field name="user.date">
<field-validator type="requiredstring">
<message>生日不允许为空!</message>
</field-validator>
<field-validator type="date">
<message>生日必须是日期!</message>
</field-validator>
</field>
</validators>
user_insert.jsp不需要修改:
<form action="user.action" method="post">
姓名: <input type="text" name="user.name" value="<s:property value="user.name" />" /> <s:property value="fieldErrors['user.name'][0]" /><br>
年龄: <input type="text" name="user.age" value="<s:property value="user.age" />" /> <s:property value="fieldErrors['user.age'][0]" /><br>
工资: <input type="text" name="user.salary" value="<s:property value="user.salary" />" /> <s:property value="fieldErrors['user.salary'][0]" /><br>
生日: <input type="text" name="user.date" value="<s:property value="user.date" />" /> <s:property value="fieldErrors['user.date'][0]" /><br><br>
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</form>
测试: 直接保持为空, 提交的结果页面, 后台报错:
报错信息:
Caught exception while loading file org/lxh/struts2demo/action/UserAction-validation.xml
Connection timed out: connect - [unknown location]
发现文件头的dtd版本不对, 换版本之后:
以前的版本:
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
现在的版本:
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
再次测试:
填写两个属性, 再测试: 报错了
此时要想显示用户自定义的验证错误的信息, 就要针对每一个Action定义个*.properties资源文件,
在UserAction.java的同级包下创建UserAction.properties:
注意: 这个资源文件的格式要固定写成: invalid.fieldvalue.字段名称 = 内容
# 年龄必须是整数
invalid.fieldvalue.user.age = \u5E74\u9F84\u5FC5\u987B\u662F\u6570\u5B57!
# 工资必须是数字
invalid.fieldvalue.user.salary = \u5DE5\u8D44\u5FC5\u987B\u662F\u6570\u5B57!
# 生日必须是日期格式(yyyy-MM-dd)
invalid.fieldvalue.user.date = \u751F\u65E5\u5FC5\u987B\u662F\u65E5\u671F\u683C\u5F0F(yyyy-MM-dd)
再次测试: 发现提交不过去了, 而且后面的提示信息根本不对
这是struts2.1.8造成的bug, 在struts2.0中不会出现这个问题.
范例: 限制输入的长度范围
修改: UserAction-validation.xml, 把为空验证放在最后, 但还有有问题
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="user.name">
<field-validator type="stringlength">
<param name="minLength">6</param>
<param name="maxLength">10</param>
<message>姓名的长度应该在${minLength}-${maxLength}之间!</message>
</field-validator>
<field-validator type="requiredstring">
<message>姓名不允许为空!</message>
</field-validator>
</field>
<field name="user.age">
<field-validator type="int">
<param name="min">1</param>
<param name="max">250</param>
<message>年龄必须在${min}-${max}之间!</message>
</field-validator>
<field-validator type="requiredstring">
<message>年龄不允许为空!</message>
</field-validator>
</field>
<field name="user.salary">
<field-validator type="double">
<message>工资必须是数字!</message>
</field-validator>
<field-validator type="requiredstring">
<message>工资不允许为空!</message>
</field-validator>
</field>
<field name="user.date">
<field-validator type="date">
<message>生日必须是日期!</message>
</field-validator>
<field-validator type="requiredstring">
<message>生日不允许为空!</message>
</field-validator>
</field>
</validators>
-----------------------------------------------------------------
自定义的验证规则:
自定义的验证规则包含以下几个内容:
1. 验证规则的操作类;
2. 在validators.xml中注册此规则;
3. 编写使用此规则的验证的资源的配置文件: XxxAction-validation.xml
使用正则表达式时最方便的一种做法
范例: 验证数字
创建包org.lxh.struts2demo.validator, 此包下创建类RegexValidator.java
public class RegexValidator extends FieldValidatorSupport {
@Override
public void validate(Object arg0) throws ValidationException {
System.out.println("***********" + arg0); // 做个测试
}
}
修改UserAction-validation.xml:
<field name="user.age">
<!-- 编写自定义的验证规则 -->
<field-validator type="regex">
<message>年龄必须是数字!</message>
</field-validator>
<field-validator type="requiredstring">
<message>年龄不允许为空!</message>
</field-validator>
</field>
在src下创建validators.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<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="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="regex" class="org.lxh.struts2demo.validator.RegexValidator"/>
</validators>
测试: http://localhost:8080/Struts2.1Project/user_insert.jsp, 点提交
控制台打印: ***********org.lxh.struts2demo.action.UserAction@5e8fa0ec
说明自定义的验证规则起作用了!
继续修改RegexValidator.java
System.out.println("***********" + super.getFieldName() + " ---> "
+ super.getFieldValue(super.getFieldName(), arg0));
1> 保持年龄为空, 提交, 打印: ***********user.age ---> null
2> 年龄输入20, 提交, 打印: ***********user.age ---> 34
说明通过这两个方法可以获取属性名和属性值, 继续修改:
String fieldName = super.getFieldName();
String value = "" + super.getFieldValue(super.getFieldName(), arg0);
if (!(value.matches("^\\d+$"))) { // 正则判断
super.addFieldError(fieldName, arg0);
}
但是这样正则在action中就硬编码了, 希望添加一个变量接收正则表达式, 然后在配置文件中接收正则进行设置
添加属性private String express;并生成getter/setter方法
private String express;
@Override
public void validate(Object arg0) throws ValidationException {
String fieldName = super.getFieldName();
String value = "" + super.getFieldValue(super.getFieldName(), arg0);
if (!(value.matches(this.express))) {
super.addFieldError(fieldName, arg0);
}
}
UserAction-validation.xml
<!-- 编写自定义的验证规则 -->
<field-validator type="regex">
<param name="express">^\d{1, 3}$</param>
<message>年龄必须是数字!</message>
</field-validator>
测试: