04-Struts1.3 Validation

 

程序中验证分为:

    服务器端验证(ActionForm)

    客户端验证(js)(测试人员会绕过js验证),因为Action是业务控制器,所以主要的后台验证应该在ActionForm中。

 

Struts的校验主要有:

    1、ActionForm的代码校验;

    2、Action的代码校验,因为Action是业务控制器,所以后台主要还是在ActionForm中;

    3、结合commons-validatot.jar的动态校验;

 

ActionForm验证:

    思想:

        ActionForm校验是最基本的校验方式,这种校验方式主要是通过重写ActionForm中的validate方法,在该方法内对所有的字段进行基本校验,如果出现不符合要求的输入,则将出错提示封装在ActionError对象里,最后将多个ActionError组合成ActionErrors对象,该对象里面封装了全部的错误提示;

 

1、首先在struts-config.xml中配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
          "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>

	<form-beans>
		<form-bean name="personForm" type="org.lxh.forms.LoginForm"></form-bean>
	</form-beans>
	<action-mappings>
		<action path="/login" name="personForm" type="org.lxh.action.LoginAction" input="/login.jsp">
			<forward name="success" path="/success.jsp" />
		</action>
	</action-mappings>

	<!-- 相当于ResourceBundle.getBundle("myResource", Locale.getDefault()); -->
	<message-resources parameter="myResource"></message-resources>
</struts-config>

说明

    在使用ActionForm的校验时应为对应的Action元素增加input属性该属性指定当校验失败后的返回页面否则不通过

 

login.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean" %>
<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="pragma" content="no-cache"> 
<meta http-equiv="cache-control" content="no-cache"> 
<meta http-equiv="expires" content="0">
<title>Insert title here</title>
</head>
<body>
<html:errors property="errorName" />
<html:form action="login.do" method="get">
	<bean:message key="name" /><html:text property="userName"></html:text>
	<html:submit value="登陆"></html:submit>
</html:form>
</body>
</html>

 说明

     jsp页面使用<html:errors />标签输出出错提示但是出错提示并没有采用硬编码的方式直接定义而是使用资源文件的key这样可以实现出错提示的国际化

  

myResource_zh_CN.properties:

name=\u7528\u6237\u540D\uFF1A
error.name={0} please login again!

  

LoginForm.java:

package org.lxh.forms;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
/**
 * @author xudongwang 2011-5-5
 * 
 */
public class LoginForm extends ActionForm {
	private String userName;
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	@Override
	public ActionErrors validate(ActionMapping mapping,
			HttpServletRequest request) {
		ActionErrors errors = new ActionErrors();
		if (userName == null || userName.trim().equals("")) {
			errors.add("errorName", new ActionMessage("error.name", "<font color='red'>用户名为空!						</font>"));			
		}
		return errors;
	}
}

  说明

     1errorNamejsp页面上<html:errors property="errorName" />的属性值

     2error.name为资源文件中的key

     3<font color='red'>用户名为空</font>表示在资源文件中keyerror.name的第一个参数

     4、validate方法中应该不涉及到相应的业务逻辑判断,在实际中经常用于判断ActionForm的属性值是否为空,长度是否符合要求等等;

 

总结:

     因为ActionErrors和ActionError都是Struts不再推荐使用的类,因此,应该尽量避免使用这种校验方式;  

 

Action验证:

     在Action里完成校验实际上就是在execute方法的前面增加数据校验的部分代码,如果通过校验,则开始调用业务逻辑,所以说Action中的校验较为灵活,但是有如下几个不便之处:

         用户需要书写大量的校验代码,使程序变得繁琐;

         数据校验应该在填充ActionForm里完成,最好能在客户端完成校验,而不是推迟到Action里才完成数据校验;

         在实际开发中,这种校验方式不仅程序开发复杂,且性能也不高;

  

Struts动态验证

    借助于commons-validator.jar的支持,Struts的校验功能非常强大,几乎不需要书写任何代码,不仅可以完成服务器端校验,同时还可以完成客户端校验,即基于javaScript的校验

    使用commons-validator.jar校验框架时,有如下几个通用配置:

       增加校验资源

       利用ValidatorPlugin加载校验资源

       ActionForm使用ValidatorForm的子类

 

动态验证:

1、将ActionForm改为:

public class UserForm extends ValidatorActionForm {
	private String userName;
	private String password;
	private String age;
	private String job;
	private String birth;
	private String email; 

说明

 1、注意这里继承的是ValidatorActionForm而不是ValidateActionForm

 2如果使用ValidatorActionForm则在validation.xml<form name="/user">中的name必须写为struts-config.xmlactionpath属性

 3、如果使用ValidateActionForm则在validation.xml<form name="UserForm">

 4、注意这里的日期和年龄用Stirng

 5、继承ValidatorActionForm是因为这个类下有属性ActionErrors和方法addActionErrors

 

2、将Struts中的核心包下的validator-rules.xml拷贝到web-inf

  

3、添加validation.xml:

<!DOCTYPE form-validation PUBLIC
          "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
          "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
<!-- 这个文件属于该项目的校验文件 -->
<form-validation>
	<!-- formset说明可以对多个表单进行验证 -->
	<formset>
		<!-- form这里说明是对userForm表单进行验证 -->
		<form name="/user">
			 <!-- field说明是对form表单下的userName字段进行验证 -->
			<field property="userName" depends="required">
		     	<!-- <arg0 key="username"/>  -->
		     	 <arg key="username" position="0"/>//其中的position为资源文件中的{n}
			</field>
			<field property="password" depends="required,minlength,maxlength">
				 <!-- 首先先检验是否为空,然后再一级一级向下检验 -->
				 <!-- <arg key="password" position="0"></arg>中默认就有name=required -->
				<arg key="password" position="0"></arg>
		<!-- resource为false表示使用自己定义的var范围,而如果为ture,则使用validator-rules.xml中默认的var -->
				<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
				<arg name="maxlength" key="${var:maxlength}" resource="false" position="1"/>
				<var>
					<var-name>minlength</var-name>
					<var-value>2</var-value>
				</var>
				<var>
					<var-name>maxlength</var-name>
					<var-value>6</var-value>
				</var>
			</field>
			<field property="age" depends="required,integer,intRange">
				<arg key="age" position="0"></arg>
				<arg name="intRange" position="1" key="${var:min}" resource="false" />
				<arg name="intRange" position="2" key="${var:max}" resource="false" />
				<var>
					<var-name>min</var-name>
					<var-value>1</var-value>
				</var>
				<var>
					<var-name>max</var-name>
					<var-value>150</var-value>
				</var>
			</field>
			<field property="job" depends="required">
				<arg key="job" position="0"/>
			</field>
			<field property="birth" depends="required,date">
				<arg key="birth" position="0"/>
			</field>
			<field property="email" depends="required,email">
				<arg key="email" position="0"></arg>
			</field>
		
		</form>
	</formset>
</form-validation>

 说明:

     1、该配置文件为用户自定义配置文件,是该项目的校验文件,负责定义每个表单域必须满足的规则,以及规则的详细说明

 

4、struts-config.xmlaction中添加

<!-- validate="true"找到这里说明会去找配置规则 -->
	<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
          "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>

	<form-beans>
		<form-bean name="userForm" type="org.lxh.forms.UserForm"></form-bean>
	</form-beans>
	<action-mappings><!-- input属性为当检校失败后返回的页面 -->
	<!-- validate="true"找到这里说明会去找用户自定义的配置进行验证 -->
		<action path="/user" name="userForm" type="org.lxh.action.UserAction" input="/user.jsp" validate="true" scope="request">
			<forward name="success" path="/success.jsp" />
		</action>
	</action-mappings>

	<!-- 相当于ResourceBundle.getBundle("myResource", Locale.getDefault()); -->
	<message-resources parameter="myResource"></message-resources>
	
	<!-- plug-in加载验证资源文件是固定的格式 -->
	<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
		<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
	</plug-in>
</struts-config>

说明

    1、注意其先后顺序如果出错了看看Eclipse提示的信息说的先后顺序

    2、这里需要指定如果不满足校验规则时,系统将返回到哪个页面,即input属性值,同时还要增加validate="true"属性

    3、标签plug-in加载验证的资源文件和自定义的资源文件,其是固定的

 

5、myResource.properties:

04-Struts1.3 Validation

username=\u7528\u6237\u540D
password=\u5BC6\u7801
age=\u5E74\u9F84
job=\u5DE5\u4F5C
birth=\u51FA\u751F\u65E5\u671F
email=\u90AE\u4EF6

errors.required={0} \u4E0D\u80FD\u4E3A\u7A7A\uFF01\uFF01\uFF01
errors.maxlength={0}\u957F\u5EA6\u6700\u957F\u4E3A{1}
errors.minlength={0}\u957F\u5EA6\u6700\u77ED\u4E3A{1}
errors.integer={0}\u5FC5\u987B\u4E3A\u6574\u6570\uFF01
errors.range={0}\u4ECE{1}\u5230{2}
errors.email={0}\u683C\u5F0F\u4E0D\u6B63\u786E\uFF01
errors.date={0}\u683C\u5F0F\u4E0D\u6B63\u786E\uFF01

 Eclipse中可以通过properties中的自带的编译器

 

6UserAction.java

package org.lxh.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.lxh.forms.UserForm;

public class UserAction extends Action {
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		UserForm userForm = (UserForm) form;
		System.out.println("用户名:" + userForm.getUserName() + ",年龄:"
				+ userForm.getAge() + ",邮箱:" + userForm.getEmail());
		return mapping.findForward("success");
	}
}

 

common-validate中常用的校验规则有如下几种

    required必填

    validwhen必须满足某个有效条件

    minlength输入必须大于最小长度

    maxlength输入必须小于最大长度

    mask输入匹配正确的正则表达式

    byteshortintegerlongfloatdouble表示只能输入特定类型的变量

    date输入必须是一个日期

    intRange:输入的数字必须在整数范围内

    floatRangedoubleRange

    email输入的必须是有效的email地址

    url:输入的必须是有效的url地址

 

添加客户端验证:

    1、在form元素增加onsubmit="return validateXxxForm(this);"属性,其中的XxxForm就是需要校验的form名,也struts-config.xml中配置的form-bean的name属性一致,也与validation.xml文件中需要校验的form的name属性一致;

    2、增加<html:javascript formName="XxxForm"/>其中XxxForm是需要校验的form名

 

jsp页面代码如下:

	<html:javascript formName="loginForm"/>
	<html:form action="login.do" onsubmit="retrun validateLogin(this)">
		<html:text property="username"></html:text>
	</html:form>

这样就可以增加javaScript校验,注意的是即使使用了javaScript校验,也不要删除页面的html:errors标签,因为该标签会在客户端校验通过,而在服务器端校验并未通过时输出提示,同时例如密码和重复密码两个输入框的输入不相同,但javaScript校验提示并为弹出,这是因为,并不是所有的校验规则都可以转换客户端的javaScript校验语法

 

ValidateForm: 基于Form name的校验

ValidateActionForm:基于Form path的校验

ValidatorForm ValidatorActionForm 区别收藏

注意DynaValidatorform(Validatorform)和DynaValidatorActionform(ValidatorActionform)的区别。前者主要的视角是formbean,而后者的视角是action。当formbean被不同的action使用时,对于不同的action而言,使用的formbean的属性集合有大有小。此时如果仍然以formbean为主体,会造成其他action的不正常使用。因此,struts中提出了DynaValidatorActionform(ValidatorActionform)。此时在validation.xml中的form标签的name属性改为action的path属性,又由于action中有attribute和name属性,validation框架就可根据这个action得到对应的formbean。例子:

<formset>
  <form name=/createAddress>
    <field property=city
          depends=required>
      <arg0 key=prompt.city/>
    </field>
  </form>
  <form name=/editAddress>
    <field property=state depends=required>
      <arg0 key=prompt.state/>
    </field>
  </form>
</formset>

首先,struts的actionServlet接收到一个请求,然后根据struts-config.xml的配置定义到相应的mapping(映射);接下来如果form的范围是request 或者在定义的范围中找不到form创建一个新的form实例;取得form实例以后,调用器reset()方法,然后将表单的参数放在form中,如果validate的属性不为fasle;调用validate()方法;如果validate()返回非空的actionerror,将会转到intput属性指定的url,如果返回空的actionerror,那么执行action的execute()方法,根据返回的actionForward确定目标url;

 

 

你可能感兴趣的:(validation,Struts1.3)