前言
正题
1.工程目录结构图:
2.以下依次帖代码:
a). web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.filterdispatcher
</filter-class>
</filter>
<filter-mapping>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>validatordate.jsp</welcome-file>
</welcome-file-list>
</web-app>
b). struts.xml
<!doctype struts public
"-//apache software foundation//dtd struts configuration 2.0//en"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="struts-validation.xml" />
</struts>
c). struts.properties
struts.ui.theme=simple
d). struts-validation.xml
<!doctype struts public
"-//apache software foundation//dtd struts configuration 2.0//en"
<package name="validationexamples" extends="struts-default"
namespace="/validation">
<action name="validatorfield"
class="com.tangjun.validator.validatoraction">
<!-- 这里input表示验证失败后指定跳转到什么地方去 -->
<result name="input" type="dispatcher">/validatordate.jsp</result>
<result>/success.jsp</result>
</action>
</package>
e). validatoraction-validation.xml
<!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="regexyearfield">
<field-validator type="mydate">
<param name="maxyear">2008</param>
<param name="minyear">1900</param>
<message>
<![cdata[ 不是一个有效的年份! ]]>
</message>
</field-validator>
</field>
<field name="regexmonthfield">
<![cdata[ 不是一个有效的月份! ]]>
<field name="regexdayfield">
<!-- 是否使用正则表达式验证日期 -->
<param name="isregex">false</param>
<!-- 使用自定义正则表达式验证日期 -->
<!--
<param name="expression"></param>
-->
<![cdata[ 当前月份的天数不对! ]]>
</validators>
说明:验证文件需要和action在同一目录下, 验证文件命名规则:验证文件xxxx-validation.xml,这个xxxx就是你前面action的类名字,xxx-xxx-validation.xml第二个xxx表示是别名.
f). validators.xml
<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="stringlength" class="com.opensymphony.xwork2.validator.validators.stringlengthfieldvalidator"/>
<validator name="regex" class="com.opensymphony.xwork2.validator.validators.regexfieldvalidator"/>
<validator name="mydate" class="com.tangjun.validator.dateex"/>
说明:在源码com.opensymphony.xwork2.validator.validatorfactory中,在325行至330那一段代码可以看出,如果不能在根目录下找到validators.xml文件,验证框架将调用默认的验证设置,即com.opensymphony.xwork2.
validator.validators目录下default.xml里面的配置信息.最后一个<validator name="mydate" class="com.tangjun.validator.dateex"/>就是我添加的默认验证器类型.
g). validatoraction
package com.tangjun.validator;
import com.opensymphony.xwork2.actionsupport;
/**
* 验证日期
*
* @author lzl
*/
public class validatoraction extends actionsupport {
private static final long serialversionuid = -4829381083003175423l;
private integer regexyearfield;
private integer regexmonthfield;
private integer regexdayfield;
public validatoraction()
{
regexyearfield = null;
regexmonthfield = null;
regexdayfield = null;
}
@override
public string execute() throws exception {
return success;
public integer getregexdayfield() {
return regexdayfield;
public void setregexdayfield(integer regexdayfield) {
this.regexdayfield = regexdayfield;
public integer getregexmonthfield() {
return regexmonthfield;
public void setregexmonthfield(integer regexmonthfield) {
this.regexmonthfield = regexmonthfield;
public integer getregexyearfield() {
return regexyearfield;
public void setregexyearfield(integer regexyearfield) {
this.regexyearfield = regexyearfield;
}
h). beanutils
import java.text.parseexception;
import java.text.simpledateformat;
import java.util.regex.matcher;
import java.util.regex.pattern;
public class beanutils {
/* 默认验证日期正则表达式 */
private static final string dateexpression = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)";
/**
* 验证日期合法性(通过抛出错误方式来验证)
* @param date
* @return
*/
public static boolean validatordate(string date) {
// 注意这个地方"yyyy-mm-dd"如果设置成了yyyy-mm-dd的话验证将失灵
simpledateformat sdf = new simpledateformat("yyyy-mm-dd");
// 这个的功能是不让系统自动转换 不把1996-13-3 转换为1997-3-1
sdf.setlenient(false);
try {
sdf.parse(date);
return true;
} catch (parseexception e) {
return false;
}
* 使用正则表达式判定日期
*
* @param str
* @param expression
public static boolean regexvalidatordate(string str, string expression) {
// 使用正则表达式进行判定
if (expression == null || expression.trim().length() == 0)
expression = beanutils.dateexpression;
pattern pattern;
// system.out.println(expression);
pattern = pattern.compile(expression, 2);
matcher matcher = pattern.matcher(str.trim());
if (!matcher.matches()) {
return true;
说明:验证日期的正则表达式就是在网上找的,可以替换成自己的.
i). dateex
import java.util.hashmap;
import com.opensymphony.xwork2.validator.validationexception;
import com.opensymphony.xwork2.validator.validators.fieldvalidatorsupport;
public class dateex extends fieldvalidatorsupport {
private static hashmap<string, integer> map = new hashmap<string, integer>();
/* 默认最大年限 */
private static final integer max_year = 2008;
/* 默认最小年限 */
private static final integer min_year = 1900;
/* 最大年限 */
private integer maxyear;
/* 最小年限 */
private integer minyear;
/* 验证日期的正则表达式 */
private string expression;
/* 是否使用正则表达式验证 */
private boolean isregex;
public dateex() {
maxyear = null;
minyear = null;
expression = null;
isregex = false;
public void validate(object object) throws validationexception {
// 获得字段的名字
string fieldname = getfieldname();
// 获得输入界面输入的值
string value = getfieldvalue(fieldname, object).tostring();
if (value == null || value.length() <= 0)
return;
if (fieldname.equals("regexyearfield"))
validateyear(value, object);
else if (fieldname.equals("regexmonthfield"))
validatemonth(value, object);
else if (fieldname.equals("regexdayfield"))
validateday(value, object);
* 验证年份
* @param object
* @throws validationexception
private void validateyear(string value, object object)
throws validationexception {
/* 设置默认值 */
if (maxyear == null) {
maxyear = max_year;
if (minyear == null) {
minyear = min_year;
integer temp = null;
temp = integer.valueof(value);
} catch (numberformatexception ex) {
addfielderrorex(getfieldname(), object);
if (temp != null) {
if (temp >= minyear && temp <= maxyear)
map.put("year", temp);
else
addfielderrorex(getfieldname(), object);
* 验证月份
private void validatemonth(string value, object object)
integer temp = integer.valueof(value);
if (temp != null) {
if (temp >= 1 && temp <= 12)
map.put("month", temp);
else
addfielderrorex(getfieldname(), object);
}
* 验证日期
private void validateday(string value, object object)
integer year = map.get("year");
integer month = map.get("month");
//直接使用天数
if(year==null || month==null)
{
return;
}
// 是否使用正则表达式验证
if (!isregex) {
if(!beanutils.validatordate(year + "-" + month + "-" + temp))
addfielderrorex(getfieldname(), object);
} else {
string strday = temp < 10 ? "0" + temp.tostring() : temp
.tostring();
string strmonth = month < 10 ? "0" + month.tostring()
: month.tostring();
//前面已经验证过了
//string stryear = year < 100 ? year < 10 ? "200" + year: "19" + year : "1" + year;
string str = year + "-" + strmonth + "-" + strday;
system.out.println("date:" + str);
if (expression == null) {
if(!beanutils.regexvalidatordate(str, null))
addfielderrorex(getfieldname(), object);
} else {
if (expression.trim().length() > 0) {
if(beanutils.regexvalidatordate(str, expression))
addfielderrorex(getfieldname(), object);
}
}
map.clear();
* 控制是否只显示一条报错信息
* @param arg0
* @param arg1
private void addfielderrorex(string arg0, object arg1) {
//if (this.getvalidatorcontext().getfielderrors().size() == 0)
addfielderror(arg0, arg1);
public integer getmaxyear() {
return maxyear;
public void setmaxyear(integer maxyear) {
this.maxyear = maxyear;
public integer getminyear() {
return minyear;
public void setminyear(integer minyear) {
this.minyear = minyear;
public string getexpression() {
return expression;
public void setexpression(string expression) {
this.expression = expression;
public boolean getisregex() {
return isregex;
public void setisregex(boolean isregex) {
this.isregex = isregex;
说明:在dateex里面,这个时候你就可以参照如intrangefieldvalidator(反编译源码)等他实现的验证器来写自己的验证器了。这里注意了,你在这个类里面每写一个属性(含get set方法),就对应的一个xxxx-validation.xml这个配置文件里面<param name="expression"></param>这个name的名字了,可以在扩展类里面直接获得了,根据传入参数进行自定义方式验证了。如下object是validate传进来的参数,表示你输入的数据对象:
// 获得字段的名字
string fieldname = getfieldname();
// 获得输入界面输入的值
string value = getfieldvalue(fieldname, object).tostring();
总结
验证器是拦截器即interceptor实现的,所以并没有看见任何代码把他们和我的action文件关联起来,他们默认的验证了,这方面可以参考max on java的文章.
转载:http://www.cnblogs.com/over140/archive/2007/12/04/982934.html