我正在使用HibernateValidator
指定的this answer中指定的表單中的兩個字段「password」和「confirmPassword」進行驗證。以下是約束描述符(驗證器接口)。使用HibernateValidator進行交叉字段驗證不會顯示錯誤消息
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頁(與<form:form></form:form>
標籤指定commandName="tempBean"
)驗證豆。
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
}
UPDATE
這一切都正常工作,並驗證預期。剩下的一件事就是在之內顯示TempBean
類以上的指定錯誤消息,即只有一個問題:如何在發生驗證違規時在JSP頁面上顯示錯誤消息?
(在兩個領域中TempBean
類作品password
和confirmPassword
的註釋@NotEmpty
並顯示違規行爲,事情是不是發生@FieldMatch
指定的消息)。
我使用基於this question驗證組爲this blog規定和它運作良好,導致顯示錯誤信息沒有中斷(因爲它看起來是)。
在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>
驗證未執行的原因是因爲這個問題中的語句「*所有內容都在同一個包'package validatorbeans;'*」中。 HibernateValidator需要**公共定義**用於約束描述符(註釋)*和約束驗證器(實現類)*,並且我將它們都聲明在同一個包中,因此缺省修飾符** no修飾符**應用於它們兩者(因爲它不可能在同一個包中聲明多於一個類或接口爲* public *)。 – Tiny 2012-08-10 03:35:20
但有一個問題仍然存在。它仍然不顯示[this]所指定的錯誤消息(http://stackoverflow.com/questions/1972933/cross-field-validation-with-hibernate-validator-jsr-303#comment8918149_2155576)評論。即使驗證執行正確,是否有人知道它不顯示錯誤消息的原因? – Tiny 2012-08-10 03:37:38
好吧,我想你應該發佈你的解決方案,關於包私人驗證器作爲答案。至於錯誤消息,它可能是一個問題,在這個問題中沒有指定form:errors聲明。 – 2012-08-10 09:14:16