业务Form从DynaValidatorActionForm继承,重写
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
方法时,调用super.validate方法或者使用Struts1.1的方法Resources.initValidator生成Validaor(打算生成后调用其validate方法)时,都报错误NoSuchMethodError:
java.lang.NoSuchMethodError: org.apache.commons.validator.Validator.addResource(Ljava/lang/String;Ljava/lang/Object;)V org.apache.struts.validator.Resources.initValidator(Resources.java:316)
原因:Validator刚出来时,是作为Struts的一个组件的形式存在的,后来为了将其作为独立组件对外提供验证服务同时考虑资源国际化的功能,从Validator中移除了addResource方法,改为使用ValidatorResources,因此报如上错误。
如使用Struts1.1自己生成的Validator,那么会在Struts内部使用到addResource方法,进而导致上述错误,因此,要解决如上问题,只能自己生成需要的Validator
参考附件中的生成代码:
InputStream in = ValidateExample.class.getResourceAsStream("validator-example.xml"); ValidatorResources resources = new ValidatorResources(in); // Create a validator with the ValidateBean actions for the bean // we're interested in. Validator validator = new Validator(resources, "ValidateBean"); // Tell the validator which bean to validate against. validator.setParameter(Validator.BEAN_PARAM, bean); ValidatorResults results = validator.validate();
项目中使用时根据出现的问题做如下修改:
1,ValidatorResources不再重复读取,而是直接从Struts1.1下的Resources中取得(Struts1.1已经通过插件导入多个Validator rules和validation的配置文件)
ValidatorResources resources = Resources.getValidatorResources(application, request);
2,由于项目中使用了自定义的Validator方法validateMaxLength,Validator中默认的ClassLoader:StandardClassLoader[Tomcat的]加载不到,会报错误:ClassNotFound:自定义的验证类
解决:设置属性使用当前上下文的ClassLoader
// UseContextClassLoader Must to be set true so that own Validation class can by loaded validator.setUseContextClassLoader(true);
3,由于上述的Validator是自己手动生成,并不是Struts1.1生成出来的,因此默认下,ActionErrors和HttpServletRequest都是null的,需要手动设置下:
// Parameter for actual Validation method to use validator.setParameter("org.apache.struts.action.ActionErrors", errors); validator.setParameter("javax.servlet.http.HttpServletRequest", request);