struts中自定义validator验证
很多时候需要验证“密码”与“重复密码”是否一致,如果放在服务器端验证就浪费资源了。
如何在客户端进行验证呢?JS可以实现,但是struts的validator框架是否能实现呢?
跟着我一起做一个例子吧。
代码见:http://download.csdn.net/user/qing2005
在原有的验证框架内容上进行改善
1. 新增MyFieldChecks.java类
-----------------------------------------------------------------------------------------------
package common;
import java.io.*;
import org.apache.struts.validator.Resources;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorUtil;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.ValidatorAction;
import org.apache.struts.action.ActionErrors;
import org.apache.commons.validator.Arg;
public class MyFieldChecks implements Serializable {
public static boolean validateCompare(Object bean,
ValidatorAction va, Field field,
ActionErrors errors,
HttpServletRequest request) {
String value = null;
if (isString(bean)) {
value = (String) bean;
} else {
value = ValidatorUtil.getValueAsString(bean, field.getProperty());
}
if (!GenericValidator.isBlankOrNull(value)) {
Arg arg=field.getArg1();
String arg1Key=field.getVarValue("compareControl");
String strCompare=ValidatorUtil.getValueAsString(bean,arg1Key);
if(strCompare==null || !value.equals(strCompare)){
errors.add(field.getKey(), Resources.getActionError(request, va, field));
return false;
}
}
return true;
}
/**
* Return <code>true</code> if the specified object is a String or a <code>null</code>
* value.
*
* @param o Object to be tested
* @return The string value
*/
protected static boolean isString(Object o) {
return (o == null) ? true : String.class.isInstance(o);
}
}
==========================================================================
2. 在validator-rules.xml最后新增片段
-----------------------------------------------------------------------------------------------
<validator name="compare" classname="common.MyFieldChecks" method="validateCompare" methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionErrors,
javax.servlet.http.HttpServletRequest" depends="required" msg="errors_compare">
<javascript>
<![CDATA[ function validateCompare(form) {
var isValid = true;
var focusField = null;
var i = 0;
var fields = new Array();
oRange = new compare();
for (x in oRange) {
var field = form[oRange[x][0]];
if ((field.type == 'text' ||
field.type == 'textarea' ||
field.type=='password') &&
(field.value.length > 0)) {
var iCompareControl = oRange[x][2]("compareControl");
var iValue=document.getElementsByName("iCompareControl").value;
if(field.value!=iValue){
if (i == 0) {
focusField = field;
}
fields[i++] = oRange[x][1];
isValid = false;
}
}
}
if (fields.length > 0) {
focusField.focus();
alert(fields.join('/n'));
}
return isValid;
}]]>
</javascript>
</validator>
==========================================================================
注意:classname是common.MyFieldChecks
3.在validation.xml中添加一个compare验证
-----------------------------------------------------------------------------------------------
<field property="reply" depends="compare">
<arg0 key="register_password"/>
<arg1 key="${var:compareControl}" resource="false"/>
<var>
<var-name>compareControl</var-name>
<var-value>password</var-value>
</var>
</field>
==========================================================================
注意:一定要定义compareControl,这和JS等都有关
4. 在JSP页面中使用验证
-----------------------------------------------------------------------------------------------
1)先测试不用JS方式
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
</ul>
</logic:messagesPresent>
<html:form action="/registerAction.do" method="post" >
......
结果:验证成功!
2)测试JS方式
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
</ul>
</logic:messagesPresent>
<html:form action="/registerAction.do" method="post" onsubmit="return validateRegisterForm(this)">
......
</html:form>
<html:javascript formName="registerForm"/>
结果:验证成功!
==========================================================================
总结:
1)环境:Winxp+JBuilder2006+Tomcat5.5+JDK1.5
2) 一开始怎么都不成功,跟踪调试后发现common.MyFieldChecks空指针异常,
百思不得其解,最后发现在“项目/RegisterModule/WEB-INF/classes/common”下没有MyFieldChecks类,
于是我把“项目/classes/common”下的MyFieldChecks类拷贝到上述目录,结果就可以了。
为了不让初学者绕圈子,请注意这点,并且,如果更改了MyFieldChecks类,也需要做上述复制。切记!
3)写JS验证时调试了很久,一方面不是很熟这种写法,另一方面每次调试都非常不方便,
后来干脆调试生成的HTML文本,调试通过后再写到validator-rules.xml中。
4)翻了很多资料、很多文章,写完整的实在太少,我想象我这样的初学者一定很多,
一次次的打击不仅仅是程序运行的失败,更是信心的考验。希望这篇文章能给你有所帮助!