복붙노트

[SPRING] HibernateValidator를 사용하여 크로스 필드 유효성 검사가 오류 메시지를 표시하지 않습니다.

SPRING

HibernateValidator를 사용하여 크로스 필드 유효성 검사가 오류 메시지를 표시하지 않습니다.

이 답변에 지정된대로 HibernateValidator를 사용하여 폼의 두 필드 "password"와 "confirmPassword"의 유효성을 검증합니다. 다음은 제약 디스크립터 (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;
    }
}

다음은

태그와 함께 commandName = "tempBean"으로 지정된 JSP 페이지로 매핑되는 유효성 검사기 빈입니다.

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에서는 문제가 발생하지 않습니다.)

이 블로그에 지정된대로이 질문을 기반으로하는 유효성 검사 그룹을 사용하고 있으며 오류 메시지 표시에 방해가되지 않는 것으로 나타났습니다.

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>

해결법

  1. ==============================

    1.이처럼 isValid 메서드를 사용해도 될까요? (이것은 실제 프로젝트에서 저에게 분명히 작용합니다) :

    이처럼 isValid 메서드를 사용해도 될까요? (이것은 실제 프로젝트에서 저에게 분명히 작용합니다) :

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

    또한 ConstraintValidator 인터페이스를 Object로 구현한다는 것을 알 수 있습니다. 양식에서 가지고있는 뒷받침 객체 여야합니다.

    그래서 구현은 다음과 같아야합니다.

     implements ConstraintValidator<FieldMatch, TempBean>
    

    이것은 아마 여기서 문제가되지 않지만, 미래의 참고 문헌으로서 이것이 어떻게되어야하는지입니다.

    최신 정보

    FieldMatch 인터페이스 / 주석 안에는 두 가지 메소드가 있습니다 : 첫 번째와 두 번째 메소드에 errorMessage를 추가하십시오.

      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를 추가하십시오.

      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 안에는 첫 번째 및 두 번째 필드 이름과 동일한 방식으로 사용합니다.

  2. from https://stackoverflow.com/questions/11890334/cross-field-validation-with-hibernatevalidator-displays-no-error-messages by cc-by-sa and MIT license