在上一篇的学习记录中,我们学习了在Struts2项目中自己手动编写代码校验用户输入的合法性,通过LoginAction中复写validate()方法,进而判断用户提交的表单字段是否合法,这一篇中,我记录下Struts2中校验数据合法性的另一种方法,即使用校验框架,与之前手动编写代码不同的是,使用Struts2提供的校验框架,我们不需要编写一行代码,只需在配置文件中做相应的配置,就可以轻松完成数据的校验,下面用一个注册的Demo来学习Struts2的校验框架:
一、新建Java web项目,添加Struts2支持
二、编写register.jsp页面,该页面的源码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>register</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<s:form action="registerAction">
<s:textfield name="username" label="用户名"></s:textfield>
<s:password name="password" label="密码"></s:password>
<s:textfield name="age" label="年龄"></s:textfield>
<s:textfield name="birthday" label="出生日期"></s:textfield>
<s:submit value="登录"></s:submit>
</s:form>
</body>
</html>
上面的register.jsp页面在浏览器中访问的效果如下图:
二、编写struts.xml文件,struts.xml文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd" >
<struts>
<package name="validateTest" extends="struts-default">
<action name="registerAction" class="com.example.action.RegisterAction">
<result name="success">/success.jsp</result>
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
我们将register.jsp中表单提交的请求交给RegisterAction来处理,如果在上一篇的话,RegisterAction需要继承ActionSupport类并复写validate()方法,但是在这一篇中不一样了,我们不再复写validate()方法了,下面是RegisterAction类的代码:
三、编写RegisterAction类
package com.example.action;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
public class RegisterAction extends ActionSupport {
private String username;
private String password;
private int age;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String execute() throws Exception {
System.out.println("call method execute");
return SUCCESS;
}
}
可以看到,上面的RegisterAction类中,我们只定义了表单中的字段对应的成员变量并为它们提供了get/set方法,然后还有一个execute()方法,再无其他方法了。那么具体的校验应该放在哪里呢?
四、编写校验配置文件
校验的配置文件是一个xml文件,其命名规则为,对应的Action的名字+"-validation",所以在这里我们要为RegisterAction类编写校验配置文件,需要在RegisterAction所在的包中新建xml文件,名称为RegisterAction-validation.xml,下面是该文件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>required string</message>
</field-validator>
<field-validator type="email">
<message>username should be email</message>
</field-validator>
<field-validator type="stringlength">
<param name="maxLength">10</param>
<param name="minLength">6</param>
<message>username should between ${minLength} and ${maxLength}</message>
</field-validator>
</field>
<field name="age">
<field-validator type="int">
<param name="min">1</param>
<param name="max">100</param>
<message>age should between ${min} and ${max}</message>
</field-validator>
</field>
<field name="birthday">
<field-validator type="date">
<param name="min">1900-1-1</param>
<param name="max">2016-1-1</param>
<message>birthday should between ${min} and ${max}</message>
</field-validator>
<field-validator type="conversion">
<param name="repopulateField">true</param>
<message>birthday convert error</message>
</field-validator>
</field>
</validators>
这里我随便加了几个验证,field标签指明了验证的是哪一个字段,field-validator标签则是一个校验器,每个字段可以包含多个校验器,field-validator中的param字段指明了校验器中的参数,message标签则表示校验不通过时显示在页面上的提示消息。
requiredstring表示该字段是必填的字符串类型,email则代表该字段为email类型,stringlength代表该字段的长度范围,int表示该字段是整型值,date表示该字段为日期类型,conversion表示该字段需要转换为日期类型。
五、给校验器设置默认的提示信息
我们运行上面的程序,访问register.jsp页面并在age字段填aaa,其他字段不填,如下图所示:
然后提交表单数据,会发现出现如下界面:
上图中的required string信息和age should between 1 and 100是我们在校验配置文件中所配置的,但是Invalid field value for field "age"是我们没有配置的,但是它却自己冒出来了,这是因为我们的age应该是int类型的值,但是输入的确实字符串类型,这个输入的值是不符合我们声明的类型的,所以Struts2框架给我们一个默认的提示信息,这个提示信息不太易懂,我们可以用一个属性文件,将默认的提示信息改成我们自定义的提示信息
六、添加属性文件,配置默认的提示信息
我们在RegisterAction类对应的包下面新建一个文件,命名为RegisterAction.properties,该文件的内容如下图所示:
上图中我们为username,password和age字段声明了默认的提示信息,注意这里的invalid.fieldvalue.这部分是不变的,添加了这个文件后,我们再次重复之前的测试,就会发现age字段的提示信息变成了我们配置的中文信息了,而不再是英文的。
七、各种校验器汇总
Struts2提供的校验器有很多种类型,下面是我收集的资料,里面包含了Struts2提供的大部分校验器类型和用法
①、Struts2内建校验器
位于xwork-2.0.4.jar压缩包中( com.opensymphony.xwork2.validator.validators)有个文件default.xml ,该文件中定义了Struts2框架内建的校验器。default.xml文件定义了常用的校验器类型。
<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>
②、各种类型校验器
1、类型转换检验器:
(1)非字段校验:
<validator type="conversion">
<param name="fieldName">myField</param>
<message>类型转换错误</message>
<param name ="repopulateField">true</param>
</validator>
(2)字段校验:
<field name="myField">
<field-validator type="conversion">
<message>类型转换错误</message>
<param name ="repopulateField">true</param>
</field-validator>
</field>
fieldName:该参数指定检查是否存在转换异常的字段名称,如果是字段校验,则不用指定该参数。
repopulateField:该参数指定当类型转换失败后,返回input页面时,类型转换失败的表单是否保留原来的错误输入。true为保留,false为不保留。
2、日期校验器:
(1)非字段校验:
<validator type="date">
<param name="fieldName">birthday</param>
<param name="min">1990-01-02</param>
<param name="max">2010-07-28</param>
<message>生日数据错误</message>
</validator>
(2)字段校验:
<field name="birthday">
<field-validator type="date">
<param name="min">1990-01-01</param>
<param name="max">2010-07-28</param>
<message key="error.birthday"></message>
</field-validator>
</field>
min:指定字段日期值的最小值,该参数为可选参数。
max:指定字段日期值的最大值,该参数为可选参数。
3、浮点数值校验器:
(1)非字段校验:
<validator type="double">
<param name="fieldName">percentage</param>
<param name="minInclusive">20.1</param>
<param name="maxInclusive">50.1</param>
<message>生日数据错误</message>
</validator>
(2)字段校验:
<field name="percentage">
<field-validator type="double">
<param name="minInclusive">20.1</param>
<param name="maxInclusive">50.1</param>
<message key="error.percentage"></message>
</field-validator>
</field>
minInclusive|minExclusive:指定字段的最小值,包含该值|不包含该值。
maxInclusive|maxExclusive:指定字段的最大值, 包含该值|不包含该值。
4、邮件地址校验器:
(1)非字段校验:
<validator type="email">
<param name="fieldName">MyEmail</param>
<message>非法的邮件地址</message>
</validator>
(2)字段校验:
<field name="MyEmail">
<field-validator type="email">
<message>非法的邮件地址</message>
</field-validator>
</field>
5、表达式校验器:
<validator type="expression">
<param name="expression">.......</param>
<message>Failed to meet Ognl Expression...</message>
</validator>
expression:该参数为一个逻辑表达式,该参数使用OGNL表达式,并基于值栈计算,返回一个Boolean类型值。
6、字段表达式校验器:
(1)非字段校验:
<validator type="fieldexpression">
<param name="fieldName">myField</param>
<param name="expression"><![CDATA[#myCreditLimit > #myGirfriendCreditLimit]]></param>
<message>My credit limit should be MORE than my girlfriend</message>
</validator>
(2)字段校验:
<field name="myField">
<field-validator type="fieldexpression">
<param name="expression"><![CDATA[#myCreditLimit > #myGirfriendCreditLimit]]></param>
<message>My credit limit should be MORE than my girlfriend</message>
</field-validator>
</field>
7、整数校验器:
(1)非字段校验:
<validator type="int">
<param name="fieldName">age</param>
<param name="min">10</param>
<param name="max">100</param>
<message>年龄必须在在${min}到${max}之间</message>
</validator>
(2)字段校验:
<field name="age">
<field-validator type="int">
<param name="min">10</param>
<param name="max">100</param>
<message>年龄必须在在${min}到${max}之间</message>
</field-validator>
</field>
8、正则表达式校验器:
(1)非字段校验:
<validator type="regex">
<param name="fieldName">myStrangePostcode</param>
<param name="expression"><![CDATA[([aAbBcCdD][123][eEfFgG][456])]></param>
</validator>
(2)字段校验:
<field name="myStrangePostcode">
<field-validator type="regex">
<param name="expression"><![CDATA[#myCreditLimit > #myGirfriendCreditLimit]]></param>
<message>My credit limit should be MORE than my girlfriend</message>
</field-validator>
</field>
expression:为必选参数,指定匹配有的表达式。
caseSensitive:指明进行匹配时,是否区分大小写,为可选参数,默认为true。
9、必填校验器:
(1)非字段校验:
<validator type="required">
<param name="fieldName">username</param>
<message>用户名不能为空</message>
</validator>
(2)字段校验:
<field name="username">
<field-validator type="required">
<message>用户名不能为空</message>
</field-validator>
</field>
10、必填字符串校验器:
(1)非字段校验:
<validator type="requiredstring">
<param name="fieldName">username</param>
<param name="trim">true</param>
<message>用户名不能为空</message>
</validator>
(2)字段校验:
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空</message>
</field-validator>
</field>
trim:可选参数,用于指定是否在校验之前对字符串进行整理,默许为true。
11、字符串长度校验器:
(1)非字段校验:
<validator type="stringlength">
<param name="fieldName">username</param>
<param name="minLength">4</param>
<param name="maxLength">10</param>
<message>用户名长度在${minLength}到${maxLength}之间</message>
</validator>
(2)字段校验:
<field name="username">
<field-validator type="stringlength">
<param name="minLength">4</param>
<param name="maxLength">10</param>
<param name="trim">true</param>
<message key="error.length.username"></message>
</field-validator>
</field>
12、网址校验器:
(1)非字段校验:
<validator type="url">
<param name="fieldName">myHomePage</param>
<message>Invalid homepage url</message>
</validator>
(2)字段校验:
<field name="myHomePage">
<field-validator type="url">
<message>Invalid homepage url</message>
</field-validator>
</field>
13、visitor校验器:
该校验器名称为:visitor,用来校验Action中定义的复合类型属性,支持简单的复合类型、数组类型、Map等集合类型。
(1)非字段校验:
<validator type="visitor">
<param name="fieldName">user</param>
<param name="context">myContext</param>
<param name="appendPrefix">true</param>
</validator>
(2)字段校验:
<field name="user">
<field-validator type="visitor">
<param name="context">myContext</param>
<param name="appendPrefix">true</param>
</field-validator>
</field>