简单的数据验证及自定义验证规则

方法一: 此方法是在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>

测试:

 

posted @ 2017-03-06 15:51  半生戎马,共话桑麻、  阅读(745)  评论(0)    收藏  举报
levels of contents