使用 HibernateValidator 进行跨字段验证不显示错误消息 [英] Cross field validation with HibernateValidator displays no error messages

查看:60
本文介绍了使用 HibernateValidator 进行跨字段验证不显示错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 HibernateValidator这个答案.以下是约束描述符(验证器接口).

I'm validating two fields, "password" and "confirmPassword" on the form for equality using HibernateValidator as specified in this answer. The following is the constraint descriptor (validator interface).

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" 标签).


The following is the validator bean which is mapped with the JSP page (as specified commandName="tempBean" with the <form:form></form:form> tag).

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页面出现验证违规时显示错误信息?

It's all working correctly and does the validation intended. Just one thing remains is to display the specified error message above the TempBean class within @FieldMatch is not being displayed i.e only one question : how to display error messages on the JSP page when validation violation occurs?

(TempBean 类中 passwordconfirmPassword 两个字段上的注释 @NotEmpty 起作用并且在违规时显示指定的消息,@FieldMatch 不会发生这种情况.

(the annotation @NotEmpty on both of the fields password and confirmPassword in the TempBean class works and displays the specified messages on violation, the thing is not happening with @FieldMatch).

我正在使用基于这个问题验证组,如这个博客和它运行良好,不会中断显示错误消息(看起来可能如此).

I'm using validation group based on this question as specified in this blog and it works well causing no interruption in displaying error messages (as it might seem to be).

在 JSP 页面上,这两个字段指定如下.

On the JSP page these two fields are specified as follows.

<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>

推荐答案

你能不能试试你的 isValid 方法是这样的?(这在现场项目中肯定对我有用):

Could you try your isValid method to be like this? (this is certainly working for me in live project):

 public boolean isValid(final Object value, final ConstraintValidatorContext cvc){
    boolean toReturn = false;

    try{
        final Object firstObj = BeanUtils.getProperty(value, firstFieldName );
        final Object secondObj = BeanUtils.getProperty(value, secondFieldName );

        //System.out.println("firstObj = "+firstObj+"   secondObj = "+secondObj);

        toReturn = firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj);
    }
    catch (final Exception e){
        System.out.println(e.toString());
    }
    //If the validation failed
    if(!toReturn) {
        cvc.disableDefaultConstraintViolation();
        //In the initialiaze method you get the errorMessage: constraintAnnotation.message();
        cvc.buildConstraintViolationWithTemplate(errorMessage).addNode(firstFieldName).addConstraintViolation();
    }
    return toReturn;
}

我还看到您正在使用 Object 实现 ConstraintValidator 接口,字面意思.它应该是您从表单中获得的支持对象:

Also I see that you are implementing the ConstraintValidator interface with an Object, literally. It should be the backing object that you have from your form:

tempBean//实际上是你在 commandName 中指定的那个.

tempBean // the one that you specify in the commandName actually.

所以你的实现应该是这样的:

So you implementation should like this:

 implements ConstraintValidator<FieldMatch, TempBean>

这可能不是这里的问题,但作为未来的参考,应该是这样.

This is probably not the issue here, but as a future reference, this is how it should be.

更新

在您的 FieldMatch 接口/注释中,您有两个方法:第一个和第二个,添加一个名为 errorMessage 的方法,例如:

Inside your FieldMatch interface/annotation you have two methods : first and second, add one more called errorMessage for example:

  Class<? extends Payload>[] payload() default {};

/**
 * @return The first field
 */
String first();

/**
 * @return The second field
 */
String second();

/**
  @return the Error Message
 */
String errorMessage

从 Validation 类中查看您的方法 - 您在那里获得了第一个和第二个字段名称.所以只需添加 errorMessage,例如:

Look inside you method from the Validation class - you are getting the first and second field names there., so just add the errorMessage, like this for example:

  private String firstFieldName;
  private String secondFieldName;
  //get the error message name
  private String errorMessagename; 
public void initialize(final FieldMatch constraintAnnotation)
{
    firstFieldName = constraintAnnotation.first();
    secondFieldName = constraintAnnotation.second();
    errorMessageNAme = constraintAnnotation.errorMessage(); 

    //System.out.println("firstFieldName = "+firstFieldName+"   secondFieldName = "+secondFieldName);
}

在 isValida 中获取它,就像你对第一个和第二个字段名称所做的一样并使用它.

Inside isValida get it, the same way you do for first and second field name and use it.

这篇关于使用 HibernateValidator 进行跨字段验证不显示错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆