【发布时间】:2012-08-07 02:05:11
【问题描述】:
我正在使用HibernateValidator 验证表单上的两个字段“密码”和“确认密码”是否相等,如this answer 中指定的那样。以下是约束描述符(验证器接口)。
package constraintdescriptor;
import constraintvalidator.FieldMatchValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = FieldMatchValidator.class)
@Documented
public @interface FieldMatch
{
String message() default "{constraintdescriptor.fieldmatch}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* @return The first field
*/
String first();
/**
* @return The second field
*/
String second();
/**
* Defines several <code>@FieldMatch</code> annotations on the same element
*
* @see FieldMatch
*/
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
public @interface List{
FieldMatch[] value();
}
}
以下是约束验证器(实现类)。
package constraintvalidator;
import constraintdescriptor.FieldMatch;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.apache.commons.beanutils.BeanUtils;
public final class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object>
{
private String firstFieldName;
private String secondFieldName;
public void initialize(final FieldMatch constraintAnnotation) {
firstFieldName = constraintAnnotation.first();
secondFieldName = constraintAnnotation.second();
//System.out.println("firstFieldName = "+firstFieldName+" secondFieldName = "+secondFieldName);
}
public boolean isValid(final Object value, final ConstraintValidatorContext cvc) {
try {
final Object firstObj = BeanUtils.getProperty(value, firstFieldName );
final Object secondObj = BeanUtils.getProperty(value, secondFieldName );
//System.out.println("firstObj = "+firstObj+" secondObj = "+secondObj);
return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj);
}
catch (final Exception e) {
System.out.println(e.toString());
}
return true;
}
}
以下是与 JSP 页面映射的验证器 bean(指定为 commandName="tempBean" 和 <form:form></form:form> 标记)。
package validatorbeans;
import constraintdescriptor.FieldMatch;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
@FieldMatch.List({
@FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match", groups={TempBean.ValidationGroup.class})
})
public final class TempBean
{
@NotEmpty(groups={ValidationGroup.class}, message="Might not be left blank.")
private String password;
@NotEmpty(groups={ValidationGroup.class}, message="Might not be left blank.")
private String confirmPassword;
public interface ValidationGroup {};
//Getters and setters
}
更新
一切正常,并进行了预期的验证。剩下的一件事是在@FieldMatch 内的TempBean 类上方显示指定的错误消息,即只有一个问题: 如何在JSP 页面上显示错误消息时发生验证违规?
(TempBean 类中 password 和 confirmPassword 两个字段上的注释 @NotEmpty 有效并在违规时显示指定消息,@FieldMatch 不会发生这种情况。
我正在使用基于this blog 中指定的this question 的验证组,它运行良好,不会中断显示错误消息(看起来可能如此)。
在JSP页面上这两个字段的指定如下。
<form:form id="mainForm" name="mainForm" method="post" action="Temp.htm" commandName="tempBean">
<form:password path="password"/>
<font style="color: red"><form:errors path="password"/></font><br/>
<form:password path="confirmPassword"/>
<font style="color: red"><form:errors path="confirmPassword"/></font><br/>
</form:form>
【问题讨论】:
-
之所以没有执行验证,是因为问题“Everything is in the same package
package validatorbeans;”中的这句话。 HibernateValidator 需要 约束描述符(注释) 和 约束验证器(实现类) 的 public 定义,并且我声明了它们在同一个包中,因此,默认修饰符 no modifier 应用于它们两者(因为在同一个包中不可能将多个类或接口声明为 public )。 -
一个问题仍然存在。它仍然不显示this 注释指定的错误消息。有人知道即使正确执行验证它也不显示错误消息的原因吗?
-
好的,我认为您应该发布有关包私有验证器的解决方案作为答案。至于错误消息,可能是问题中未指定的 form:errors 声明存在问题。
-
在我的第一条评论中这是一个错误(在最后一行)“因为在同一个包中不可能将多个类或接口声明为公共”。它应该在同一个 file 中,而不是在同一个包中。我真的为这个错误道歉。
-
您是否能够显示错误消息以进行简单验证?更重要的是,您使用的是什么 servlet 和 JSP 库?根据您的 JSP sn-p & 标签,我猜是 Spring MVC。
标签: spring jsp spring-mvc bean-validation hibernate-validator