程序中验证分为:
服务器端验证(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;
}
}
说明:
1、errorName为jsp页面上<html:errors property="errorName" />的属性值
2、error.name为资源文件中的key
3、<font color='red'>用户名为空!</font>表示在资源文件中key为error.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.xml中action的path属性;
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.xml,在action中添加
<!-- 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:

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中的自带的编译器
6、UserAction.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:输入匹配正确的正则表达式
byte、short、integer、long、float、double:表示只能输入特定类型的变量
date:输入必须是一个日期
intRange:输入的数字必须在整数范围内
floatRange、doubleRange
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;
本文深入探讨了Struts框架中的表单验证机制,包括ActionForm验证、Action验证以及动态验证(借助commons-validator.jar)的具体实现与应用。详细介绍了如何在不同场景下进行表单验证,包括配置文件、资源文件的使用,以及如何实现客户端验证。同时,通过示例代码展示了如何在实际项目中应用这些验证技术,确保数据输入的安全性和正确性。
308

被折叠的 条评论
为什么被折叠?



