验证

Strut2验证可以通过一个XML配置文件和注解的方式来实现,当然手工验证(编码验证)也是支持的。同时也可以通过XML和注解共同使用的方式实现联合验证。

Struts2的验证是通过validationworkflow拦截器实现的,它们都属于default interceptor stackvalidation拦截器用于验证并组织错误消息workflow拦截器用于检测是否包含错误消息,假如有,它将返回结果为input所指向的页面,并将错误消息和原先输入的数据一同呈现给客户。

如果您的程序中使用了默认的验证(或者转换器)而没有提供为input的结果,则将出现错误。

//ActionSupport提供validate的方法
public void validate() {	
	if(name == null || name.length() == 0){
//这个应该算是声明式配置
		addFieldError("name",getText("error.name.empty"));		
//错误调用的也是input值	这是硬编码
		//addFieldError("name","用户名不存在");
		}
	}



验证方法执行完,控制权返回到工作流拦截器,该方法没有返回值,秘密就在于校验生成的错误消息.工作流拦截器会查看是否有错误消息生成,如果有的话,他会更改请求的工作流,终止请求处理并立即返回到用户的输入表单页面.在页面上会显示错误消息.

ValidationAware接口也定义了判断错误消息是否存在的方法,工作流拦截器会使用它们来决定是否需要重定向工作流到input页面,若有错误发生,拦截器会寻找input结果.

示例

基础验证Basic Validation

说到底就是在正常基础上多了ValidateAction-validation.xml这个文件。。

让我们一步一步做一个基础验证的示例

1. 步骤一:创建输入表单

create.jsp

<body>

<s:form action="helloValidation">

<s:textfield name="name" label="姓名"></s:textfield>

<s:textfield name="age" label="年龄"></s:textfield>

<s:textfield name="address" label="籍贯"></s:textfield>

<s:submit value="提交"></s:submit>

</s:form>

</body>

2. 步骤二:创建动作类

HelloAction.java

package cn.wzhting;

 

import com.opensymphony.xwork2.ActionSupport;

 

public class HelloAction extends ActionSupport {

 

private static final long serialVersionUID = 117358005790515177L;

private String name;

private Integer age;

private String address;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

}

3. 步骤三:创建验证器。验证配置文件必须是以下两种形式之一

l <ActionClassName>-validation.xml

l <ActionClassName>-<ActionAliasName>-validation.xml

HelloAction-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="name">

<field-validator type="requiredstring">

<message>请输入姓名</message>

</field-validator>

</field>

<field name="age">

<field-validator type="int">

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

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

<message>年龄为13~19周岁的才允许填写</message>

</field-validator>

</field>

</validators>

4. 步骤四:请确认你的struts.xml文件中该动作有input的结果。

struts.xml

<action name="helloValidation" class="cn.wzhting.HelloAction">

<result name="success">/createConfirm.jsp</result>

<result name="error">/error.jsp</result>

<result name="input">/create.jsp</result>

</action>

假如你没有这样设置,你将会得到“No result defined for action *** and result input”的错误提示。

客户端验证Client-side Validation

让我们一步一步做一个客户端验证的示例

l <s:form>标签的validate设置为true;

l 某些主题(themes)不支持客户端验证;

步骤一:创建输入表单

create.jsp

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Validation - Basic</title>

<s:head/>

</head>

<body>

<s:form action="helloValidation.action" validate="true">

<s:textfield name="name" label="姓名"></s:textfield>

<s:textfield name="age" label="年龄"></s:textfield>

<s:textfield name="address" label="籍贯"></s:textfield>

<s:submit value="提交"></s:submit>

</s:form>

</body>

注意:

l 虽然使用了<s:head/>标签,此处我们只是利用其默认样式。

l 虽然struts2中的动作带不带action后缀效果一样,但是在此处最好加上action后缀,不然会报错。

步骤二、三、四 《基础验证 Basic Validation》一节,此处省略。

动作和命名空间(Action and namespace)

如果表单提交到的动作不在默认命名空间里,在使用<s:form>时必须指定其namespace属性。例如,helloValidation在命名空间/ns内,可能的struts.xml如下:

struts.xml

<package name="p1" extends="struts-default" namespace="/ns">

<action name="helloValidation" class="cn.wzhting.HelloAction">

<result name="success">/createConfirm.jsp</result>

<result name="error">/error.jsp</result>

<result name="input">/create.jsp</result>

</action>

</package>

输入表单如下:

create.jsp

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Validation - Basic</title>

<s:head/>

</head>

<body>

<s:form action="helloValidation.action" validate="true" namespace="/ns">

<s:textfield name="name" label="姓名"></s:textfield>

<s:textfield name="age" label="年龄"></s:textfield>

<s:textfield name="address" label="籍贯"></s:textfield>

<s:submit value="提交"></s:submit>

</s:form>

</body>

看上去应该能正常运行,客户端验证将不能struts必须准确的知道动作所在的命名空间(不是通过URL),因此正确的写法如下:

create.jsp

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Validation - Basic</title>

<s:head/>

</head>

<body>

<s:form action="/ns/helloValidation.action" validate="true">

<s:textfield name="name" label="姓名"></s:textfield>

<s:textfield name="age" label="年龄"></s:textfield>

<s:textfield name="address" label="籍贯"></s:textfield>

<s:submit value="提交"></s:submit>

</s:form>

</body>

 验证_第1张图片


编写自定义的验证程序

编写步骤:

l 实现特定的接口,常用的是继承已经实现相应接口的类,如com.opensymphony.xwork2.validator.validators.FieldValidatorSupport或com.opensymphony.xwork2.validator.validators.ValidatorSupport

l 注册该验证程序

 

验证的实现全是靠验证器(validators)完成的,这些验证器必须在ValidatorFactory(利用registerValidator方法)中进行注册。自定义的验证器可以通过一种很简单的方式注册进去,那就是在构建路径中(/WEB-INF/classes)中创建validators.xml文件,在该文件中声明你要注册的验证器

以下列出了struts2框架中默认的验证器,自定义的验证器的定义语法可以参考以下内容。

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="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>

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

注意:

struts2.0.7和之前的版本中,如果加入了自定义的验证器,你必须同时还得拥有一份默认验证器的拷贝,即在类路径中的validators.xml的验证器会覆盖掉默认的验证器。但之后的版本则避免了此问题。

示例

用来检查密码强度的验证程序。规则:至少包含一个数字、一个小写字母和一个大写字母。此外该验证程序还可以接受一个minLength参数,用户可以通过设置该参数来设置一个可接受的口令的最小长度。

1、编写验证器

package wiva.struts2.train.validator;

import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

public class StrongPasswordValidator extends FieldValidatorSupport {
	private int minLength = -1;
	
	public int getMinLength() {
		return minLength;
	}

	public void setMinLength(int minLength) {
		this.minLength = minLength;
	}

	public void validate(Object object) throws ValidationException {
		String feildName = getFieldName();
		String value = (String)getFieldValue(feildName, object);
		if(value == null||value.length()==0){
			addFieldError(feildName, object);
		}else if((minLength>-1)&&(value.length()<minLength)){
			addFieldError(feildName, object);
		}else if(!isPasswordStrong(value)){
			addFieldError(feildName, object);
		}
	}
	private static final String GROUP1 = "abcdefghijklmnopqrstuvwxyz";
	private static final String GROUP2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	private static final String GROUP3 = "0123456789";
	protected boolean isPasswordStrong(String password) {
		boolean ok1 = false;
		boolean ok2 = false;
		boolean ok3 = false;
		int length = password.length();
		for(int i=0;i<length;i++){
			if(ok1&&ok2&&ok3)
				break;
			String character = password.substring(i,i+1);
			if(GROUP1.contains(character)){
				ok1 = true;
				continue;
			}
			if(GROUP2.contains(character)){
				ok2 = true;
				continue;
			}
			if(GROUP3.contains(character)){
				ok3 = true;
				continue;
			}
		}
		return ok1&&ok2&&ok3;
	}

}



 2、注册验证器(WEB-INF/classes/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="strongpassword" class="wiva.struts2.train.validator.StrongPasswordValidator"></validator>
</validators>



3.使用(*Action-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="password">
		<field-validator type="strongpassword">
			<param name="minLength">6</param>
			<message>少包含一个数字、一个小写字母和一个大写字母且不能少于6个</message>
		</field-validator>
	</field>
	
</validators>



编程验证

之前所使用和编写的验证程序都是声明性的,先声明,后使用。在某些场合,可能因为验证规则过于复杂,用声明性验证会困难一些,因而需要为它们编写必要的验证代码,即需要进行“编程验证”

Struts2提供了一个com.opensymphony.xwork2.Validateable接口,可以在自己的动作类内通过实现该接口以提供编程验证的功能。

package com.opensymphony.xwork2;

public interface Validateable {

  void validate();

}

如果动作类实现了该接口,Struts会调用它的validate方法,所以应把用来验证用户输入的代码编写在这个方法内。ActionSupport实现了该接口,因此动作类继承ActionSupport就不需要直接实现该接口了。

示例1

用户注册程序。如果用户输入的用户名已经在数据库中存在了,则要求用户换另外一个用户名进行注册。

动作类

package wiva.struts2.train.action;

import java.util.LinkedList;
import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class UserRegAction extends ActionSupport {
	/**
	 * 
	 */
	private static final long serialVersionUID = 2227569782574386186L;
	private String userName;
	private String password;
	private static List<String> userNames = new LinkedList<String>();
	static{
		//实际业务中,userNames中的内容应该从数据库中查询出来
		userNames.add("admin");
		userNames.add("wzhting");
	}
	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 void validate() {
		if(userNames.contains(userName))
			addFieldError("userName", "用户名"+userName+"已经存在");
	}
	
}



示例2

若针对某个动作方法单独进行验证,你需要编写一个方法public void validate方法名().方法名的第一个字母大写

        <s:form action="addAction">
		<s:textfield name="userName" label="用户名"></s:textfield>
		<s:submit value="添加"></s:submit>
	</s:form>
	<s:form action="editAction">
		<s:textfield name="userName" label="用户名"></s:textfield>
		<s:submit value="修改"></s:submit>
	</s:form>



动作类

package wiva.struts2.train.action;

import com.opensymphony.xwork2.ActionSupport;

public class ValidateAction extends ActionSupport {
	private static final long serialVersionUID = -739143505400361615L;
	private String userName;
	
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String add(){
		return SUCCESS;
	}
	public String edit(){
		return SUCCESS;
	}
	public void validateAdd() {
		if(userName==null||userName.length()==0)
			addFieldError("userName","请输入用户名");
	}
	
}






你可能感兴趣的:(验证)