Struts2 校验框架

Struts2 和Struts1同样也提供了校验框架,但在Struts2 已经不再把校验框架做为一个插件,而是已经内置到了Struts2中,而且配置起来更为简单方便,功能也更强大。

下面以一个例子来说明Struts2校验框架的使用。

1在myeclipse 中创建一个web工程,在src目录下创建struts.xml 配置文件,添加好xml标头,配置web.xml文件。

1-1.了解一下我做的简单例子需求,实现一个用户注册的功能,用户信息包括用户名,密码,确认密码,年龄,出生日期,毕业日期等信息。在注册过程需要提供以下校验规则:

[1] 用户必填,长度在6-10之间

[2] 密码和确认密码必填,两次输入密码要一致长度,在6-10之间

[3] 年龄必须是数字 界于1-150之间

[4] 出生日期和毕业日期必填,且出生日期必须早于毕业日期

要求:使用struts2 提供的xml配置方式进行校验。

1-2.首先创建一个register.jsp 页面,代码如下:

<%@ page language="java"  pageEncoding="UTF-8"%>

<%@ taglib uri="/struts-tags" prefix="s" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<title>register page</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">

<SCRIPT type="text/javascript">

function validate(){

var usernameValue=document.getElementById("username").value;

var passwordValue=document.getElementById("password").value;

var repasswordValue=document.getElementById("repassword").value;

if(usernameValue.length==0){

alert("username should not be blank!");

return false;

}else if(usernameValue.length<6 || usernameValue.length>10){

alert("username should be between 6 and 10 !");

return false;

}

return true;

}

</SCRIPT>

</head>

<body>

<s:fielderror cssStyle="color:red;"/>

<s:form action="register2" theme="simple">

<table border="1" cellpadding="0" cellspacing="0">

<tr>

<td>username</td>

<td><s:textfield name="username"  label="usernmae" id="username"/></td>

</tr>

<tr>

<td>password</td>

<td><s:password name="password" label="password" id="password"/></td>

</tr>

<tr>

<td>repassword</td>

<td><s:password name="repassword" label="repassword" /></td>

</tr>

<tr>

<td>age</td>

<td><s:textfield  name="age" label="age"/></td>

</tr>

<tr>

<td>birthday</td>

<td><s:textfield name="birthday" label="birthday"/></td>

</tr>

<tr>

<td>graduation</td>

<td><s:textfield name="graduation" label="graduation"/></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><s:submit /></td>

</tr>

</table>

</s:form>

</body>

</html>

显示如下:

1-3.创建RegisterAction 代码如下:

package com.snt.struts2.action;

import java.util.Calendar;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction extends ActionSupport {

private String username;

private String password;

private String repassword;

private int age;

private Date birthday;

private Date graduation;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

public Date getGraduation() {

return graduation;

}

public void setGraduation(Date graduation) {

this.graduation = graduation;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public String getRepassword() {

return repassword;

}

public void setRepassword(String repassword) {

this.repassword = repassword;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String execute() throws Exception {

return SUCCESS;

}

/**

* 注册1方法

* @return

* @throws Exception

*/

public String register1() throws Exception {

return SUCCESS;

}

public String abc()throws Exception{

System.out.println("abc method invoke!");

return SUCCESS;

}

public String xyz()throws Exception{

System.out.println("abc method invoke!");

return SUCCESS;

}

public void validateAbc(){

System.out.println("valide abc()");

}

public void validateXyz(){

System.out.println("valide xyz()");

}

/***

* 当遇到类型转化时,struts2自动生成一条错误信息,放到

* fielderrors 中

*/

public void validateExecute() {

//当用户直接访问action时,action的属性都是null

//防止NullPointException

System.out.println("validate()...........");

if(null==username || username.length()<6 || username.length()>10){

this.addActionError("username invalid!");

}

if(null==password ||  password.length()<6 || password.length()>10){

this.addActionError("password is invalid!");

}else if(null==repassword ||  repassword.length()<6 || repassword.length()>10){

this.addActionError("password is invalid!");

}else if(!password.equals(repassword)){

this.addActionError( "tow password is not be same!");

}

if(age<=0 || age>150){

System.out.println("ERROR");

this.addActionError( "age is invalid!");

}

if(null!=birthday && null!=graduation){

Calendar c1=Calendar.getInstance();

c1.setTime(birthday);

Calendar c2=Calendar.getInstance();

c2.setTime(graduation);

if(!c1.before(c2)){

this.addActionError("birthday shoud before graduation!");

}

}

}

public void validateRegister1() {

//当用户直接访问action时,action的属性都是null

//防止NullPointException

System.out.println("validate()...........");

System.out.println("validate()...........");

if(null==username || username.length()<6 || username.length()>10){

this.addFieldError("username", "username is invalid");

}

if(null==password ||  password.length()<6 || password.length()>10){

this.addFieldError("password", "password is invalid!");

}else if(null==repassword ||  repassword.length()<6 || repassword.length()>10){

this.addFieldError("password", "password is invalid!");

}else if(!password.equals(repassword)){

this.addFieldError("password", "tow password is not be same!");

}

if(age<0 || age>150){

this.addFieldError("age", "age is invalid!");

}

if(null==birthday){

this.addFieldError("birthday", "birthday invalid!");

}

if(null==graduation){

this.addFieldError("graduation", "graduation  invalid!");

}

if(null!=birthday && null!=graduation){

Calendar c1=Calendar.getInstance();

c1.setTime(birthday);

Calendar c2=Calendar.getInstance();

c2.setTime(graduation);

if(!c1.before(c2)){

this.addFieldError("birthday","birthday shoud before graduation!");

}

}

}

}

1-4.采用Struts2的检验框架需要创建一个配置文件,规则如下,我们需要在与所有要进行校验的Action同级别目录下创建一个xml文件,命名必须遵守规则:Action名-validation.xml 文件,对于这个例子就是:RegisterAction-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="username">

<field-validator type="requiredstring" short-circuit="false">

<param name="trim">true</param>

<message>username shoudld not be blank!</message>

</field-validator>

<field-validator type="stringlength">

<param name="minLength">6</param>

<param name="maxLength">10</param>

<message>username should be between ${minLength} and ${maxLength}</message>

</field-validator>

</field>

<field name="password">

<field-validator type="requiredstring">

<message>password should not be balank!</message>

</field-validator>

<field-validator type="stringlength">

<param name="minLength">6</param>

<param name="maxLength">10</param>

<message>password should be between ${minLength} and ${maxLength}</message>

</field-validator>

</field>

<field name="repassword">

<field-validator type="requiredstring">

<message>repassword should not be balank!</message>

</field-validator>

<field-validator type="stringlength">

<param name="minLength">6</param>

<param name="maxLength">10</param>

<message>repassword should be between ${minLength} and ${maxLength}</message>

</field-validator>

</field>

<field name="repassword">

<field-validator type="fieldexpression">

<param name="expression"> <![CDATA[(password==repassword)]]>

</param>

<message>two password should be the same! </message>

</field-validator>

</field>

<field name="age">

<field-validator type="int">

<param name="min">1</param>

<param name="max">150</param>

<message>age should be between ${min} and ${max}</message>

</field-validator>

</field>

<field name="birthday">

<field-validator type="required">

<message>birthday should not be blank!</message>

</field-validator>

<field-validator type="date">

<param name="min">2001-01-01</param>

<param name="max">2004-01-01</param>

<message>birthday should be between ${min} and ${max}</message>

</field-validator>

</field>

<field name="graduation">

<field-validator type="required">

<message>graduation should not be blank!</message>

</field-validator>

<field-validator type="date">

<param name="min">2005-01-01</param>

<param name="max">2008-01-01</param>

<message>birthday should be between ${min} and ${max}</message>

</field-validator>

</field>

</validators>

对于Struts2提供的校验方式有两种:1 字段校验   2 非字段校验

针对字段校验就如上面xml文件所写,是针对字段,字段中再配置各种校验规则。而对于非字段指的是:先定义好校验器,校验器中再配置针对那个字段进行校验。其实两种校验方式底层使用机制都是一样。

比如上面针对用户的校验,如下定义:

<field name="username">

<field-validator type="requiredstring" short-circuit="false">

<param name="trim">true</param>

<message>username shoudld not be blank!</message>

</field-validator>

<field-validator type="stringlength">

<param name="minLength">6</param>

<param name="maxLength">10</param>

<message>username should be between ${minLength} and ${maxLength}</message>

</field-validator>

</field>

先用<field>标签描述要校验的字段,里面定义校验器,使用<field-vaidator>标签,这个标签中有个type 属性,这个属性指是就是校验规则,比如:requiredstring  就代表必填表的字符串,表明这个信息是用户必须输入的。需要注意的是type属性不是随便写的,这个名字会对应struts2 提供的各样校验器类。我们查找strust2 原代码会在xwork jar包中的com.opensymphony.xwork2.validator.validators包下面找到一个default.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">

<!-- START SNIPPET: validators-default -->

<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="stringlength"class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>

<validator name="regex"class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>

</validators>

<!--  END SNIPPET: validators-default -->

这里面大家可以很清楚的看到,配置是每个校验器对应的名称和校验需要的类,每个校验都有一个name属性,这个属性就是我们在ActionName-validation.xml 配置文件中<field-validator> 标签type属性要可以使用的值,同样我们也可心在com.opensymphony.validator.validators包中找到对应的校验器类,比如:我们可以打开

com.opensymphony.validator.validators.RequiredStringValidator 类源代码如下:

/*

* Copyright (c) 2002-2006 by OpenSymphony

* All rights reserved.

*/

package com.opensymphony.xwork2.validator.validators;

import com.opensymphony.xwork2.validator.ValidationException;

public class RequiredStringValidator extends FieldValidatorSupport {

private boolean doTrim = true;

public void setTrim(boolean trim) {

        doTrim = trim;

    }

public boolean getTrim() {

return doTrim;

}

public void validate(Object object) throws ValidationException {

String fieldName = getFieldName();

Object value = this.getFieldValue(fieldName, object);

if (!(value instanceof String)) {

addFieldError(fieldName, object);

} else {

String s = (String) value;

if (doTrim) {

s = s.trim();

}

if (s.length() == 0) {

addFieldError(fieldName, object);

}

}

}

}

在usrename 的必须字段校验串中有这样一段配置

<param name="trim">true</param>

大家再年,上面红色背景显示的一段代码,就可以明白,这个参数就是赋值为这个属性的。表明校验时要去掉字符串两边的空格。当然如果有其它方法,也可以这样使用<param>标签传参数。<message>标签中信息是校验失败后要显示的信息。

上面为username 定义了一个必填字段校验器外,还添加了一个长度限制的校验器stringlength 校验器。其它配置都是一样的!

上面说过了,字段校验有两种,一种是上面所说的字段校验,另一种是非字段校验,下面我们看一下:

针对username 的非字段校验配置如下:

<validator type="requiredstring">

<param name="fieldName">username</param>

<message>username should not be blank</message>

</validator>

<validator type="stringlength">

<param name="fieldName">username</param>

<param name="minLength">6</param>

<param name="maxLength">10</param>

<message>username should  be between ${minLength} and

${maxLength}</message>

</validator>

看上面的配置,先定义一个校验器,使用<validator>标签,然后在标签里配置的参数

<param name="fieldName">username</param>

name 属性是不变的,使用fieldName 代表字段名,标签中间的值代表要校验的字段,下面的<message>标签中信息是校验失败后要显示的信息。其实非字段校验和这字段校验没什么区别,只是配置文件不一样而已,在开发中建议使用字段校验,会更清晰一点!

1-5.OK这样配置,整个配置文件都可以生产了,运行测试应用,显示如下:

OK,校验测试成功。

另外在校验过程中还要注意一些问题:

多方法Action情况如何使用配置文件进行校验?

我们知道大多数据情况下,Action可能会有多个方法,面我们上面所说的都是针对execute()方法进行的校验,如果存在多方法的情况下,需要进行校验的信息肯定是不样的,一个配置文件肯定解决不了问题,所有在多方式需要校验的情况下,我们需要在Action同级别的目录下,创建命名规则如下的配置文件:ActionName-method-validation.xml 配置文件,比如:RegisterAction中有个test()方法需要校验,可以创建

RegisterAction-test-validation.xml 配置文件进行配置,这个文件就会针对tets()方法进行校验,但是需要注意的是:在调用test()方法时,使用RegisterAction-test-vaidation.xml  文件进行校验后,还会调用RegisterAction-vaidation.xml 文件进行校验,这样的话,肯定会产生干扰,为了解决这样问题,可以在开发过程中,不提供RegisterAction-validtion.xml 这样的文件,对于execute()方法,可以提供一个RegisterAction-execute-validation.xml 文件进行配置校验。

 XML方式校验与硬编码方式校验的选择|

我们采用了XML 配置文件的方式进行校验,介是Action中的validate()方法同时也会被执行的,这时一些校验就可能会重复!所以在开发过程中,我们只采用一种方式,要么使用XML方式进行校验,要么采用硬编码的方式进行校验,而不建议混合使用的方式;一般情况下,我们采用XML方式进行校验,而且XML方式可以满足我们的需求,在业务特别复杂或校验粒度比较细的情况下我们可以采用硬编码的方式校验。

1.6.Struts2 XML配置方式进行是服务器端校验,当然在开发过程中我们经常会需要客户端校验,Struts2也提供了客户端校验功能,使用客户端校验,首先页面中Struts2 标签的主题不能设为simple主题,另外form标签的validate 属性要改为true。但是Struts2提供的这种客户端校验功能是非常有限的,所有在需要使用客户端校验的情况,可以采用javascript 或Ajax的方式进行校验,会更灵活一点。

Struts2 校验框架学习笔记的更多相关文章

  1. phalcon(费尔康)框架学习笔记

    phalcon(费尔康)框架学习笔记 http://www.qixing318.com/article/phalcon-framework-to-study-notes.html 目录结构   pha ...

  2. Yii框架学习笔记(二)将html前端模板整合到框架中

    选择Yii 2.0版本框架的7个理由 http://blog.chedushi.com/archives/8988 刚接触Yii谈一下对Yii框架的看法和感受 http://bbs.csdn.net/ ...

  3. JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

    前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...

  4. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  5. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

  6. JavaSE中线程与并行API框架学习笔记1——线程是什么?

    前言:虽然工作了三年,但是几乎没有使用到多线程之类的内容.这其实是工作与学习的矛盾.我们在公司上班,很多时候都只是在处理业务代码,很少接触底层技术. 可是你不可能一辈子都写业务代码,而且跳槽之后新单位 ...

  7. JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?

    前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...

  8. scrapy爬虫框架学习笔记(一)

    scrapy爬虫框架学习笔记(一) 1.安装scrapy pip install scrapy 2.新建工程: (1)打开命令行模式 (2)进入要新建工程的目录 (3)运行命令: scrapy sta ...

  9. TensorFlow机器学习框架-学习笔记-001

    # TensorFlow机器学习框架-学习笔记-001 ### 测试TensorFlow环境是否安装完成-----------------------------```import tensorflo ...

随机推荐

  1. Asp.net mvc 实时生成缩率图到硬盘

    之前对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实时生成图片缩率图服务. ...

  2. HBase(二)CentOS7.5搭建HBase1.2.6HA集群

    一.安装前提 1.HBase 依赖于 HDFS 做底层的数据存储 2.HBase 依赖于 MapReduce 做数据计算 3.HBase 依赖于 ZooKeeper 做服务协调 4.HBase源码是j ...

  3. 【hihoCoder】#1513 : 小Hi的烦恼

    题解 我会五维数点辣 只要用个bitset乱搞就好了 记录一下rk[i][j]表示第j科排名为i的是谁 用30000 * 5个大小为30000的bitset s[i][j]是一个bitset表示第j科 ...

  4. 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) B - Enlarging Enthusiasm dp好题

    B - Enlarging Enthusiasm 感觉做到过好多的dp题都会和单调性结合在一起. 思路:dp[ s ][ pre ][ res ] 表示的是已选择了s,上一个是pre, 还有res 的 ...

  5. CSUOJ 1021 组合数末尾的零 二进制

    Description 从m个不同元素中取出n (n ≤ m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数.组合数的计算公式如下: C(m, n) = m!/((m - n)!n! ...

  6. Java反射机制demo(三)—获取类中的构造函数

    Java反射机制demo(三)—获取类中的构造函数 1,获取类中所有的构造函数 如下面的代码中所示,这个类中显式的构造函数有五个. 空构造: public UserInfo() 带参构造有四个: pu ...

  7. Python下读取转换unicode的json格式

    转自: https://blog.csdn.net/felcon/article/details/38524317 JSON(JavaScript Object Notation) 是一种轻量级的数据 ...

  8. python脚本 pyqt 打包成windows可执行exe文件 pyinstaller

    今天学习pyqt,做了一些好玩的东西. 好奇之中想试试python脚本编译成可执行文件,一顿查询之后成功了! 我的环境是: windows10 64bit    python3.5    pyqt5 ...

  9. PHP cURL中CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT的区别

    CURLOPT_CONNECTTIMEOUT用来告诉PHP脚本在成功连接服务器前等待多久(连接成功之后就会开始缓冲输出),这个参数是为了应对目标服务器的过载,下线,或者崩溃等可能状况: CURLOPT ...

  10. BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流

    https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...