3

UserPropertyForm内部に2つのオブジェクトを含む複雑なオブジェクトがあります。

    public class ComplexUserForm {
       int userType;

       @Valid
       UserPropertyForm property1;
       UserPropertyForm property2;
       ...
    }

    public class UserPropertyForm {
       @NotEmpty
       @Length(max = 255)
       private String title;
       @NotEmpty
       @Length(min = 100)
       private String description;
       ...
    }

property1毎回検証する必要があるので、としてマークを付けました@Valid。次の場合にのみ検証する
必要がありますproperty2userType == 2

フィールドproperty2用に持っているアノテーションを使用して簡単な方法で検証できるかどうか誰かが言うことができますか?UserPropertyForm

助けてくれてありがとう。

4

2 に答える 2

4
You can use this custom annotation above your class.

    @ValidateIfAnotherFieldHasValue(
            fieldName = "userType",
            fieldValue = "2",
            dependFieldName = "property2")
  public class ComplexUserForm {
       int userType;

       @Valid
       UserPropertyForm property1;
       UserPropertyForm property2;

getUserType()。equals( "2")の場合にのみproperty2を検証します。

エラーメッセージはproperty2.fieldnameに送信されるため、property2 <form:errors path="property2.*"/>からすべてのエラーをまとめてキャッチする場合は、JSPで必要になります。

public class ValidateIfAnotherFieldHasValueValidator
implements ConstraintValidator<ValidateIfAnotherFieldHasValue, Object> {

private String fieldName;
private String expectedFieldValue;
private String dependFieldName;

@Override
public void initialize(final ValidateIfAnotherFieldHasValue annotation) {
    fieldName          = annotation.fieldName();
    expectedFieldValue = annotation.fieldValue();
    dependFieldName    = annotation.dependFieldName();
}

@Override
public boolean isValid(final Object value, final ConstraintValidatorContext ctx) {

    if (value == null) {
        return true;
    }

    try {
        final String fieldValue       = BeanUtils.getProperty(value, fieldName);
        final Object dependFieldValue = PropertyUtils.getProperty(value, dependFieldName);

        if (expectedFieldValue.equals(fieldValue)) {

            ctx.disableDefaultConstraintViolation();
            ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
            Validator validator = factory.getValidator();

            Set<ConstraintViolation<Object>> errorList = validator.validate(dependFieldValue);

            for(ConstraintViolation<Object> error : errorList) {

                 ctx.buildConstraintViolationWithTemplate(error.getMessageTemplate())
                 .addNode(dependFieldName+"."+error.getPropertyPath())
                 .addConstraintViolation();
            }

            return errorList.isEmpty();
        }

    } catch (final NoSuchMethodException ex) {
        throw new RuntimeException(ex);

    } catch (final InvocationTargetException ex) {
        throw new RuntimeException(ex);

    } catch (final IllegalAccessException ex) {
        throw new RuntimeException(ex);
    }

    return true;
}

}

と:

@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidateIfAnotherFieldHasValueValidator.class)
@Documented
public @interface ValidateIfAnotherFieldHasValue {

    String fieldName();
    String fieldValue();
    String dependFieldName();

    String message() default "{ValidateIfAnotherFieldHasValue.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        ValidateIfAnotherFieldHasValue[] value();
    }

}
于 2015-10-23T01:19:53.553 に答える
1

私はvalidateフォームのバリデーターの方法でそれを行うことができました:

public void validate(final Object obj, final Errors errors) {
   final ComplexUserForm form = (ComplexUserForm) obj;
   if (form.getUserType() == 2) {
      ClassValidator<UserPropertyForm> offered2Validator = new ClassValidator<UserPropertyForm>(UserPropertyForm.class);
      InvalidValue[] property2InvalidValues = property2Validator.getInvalidValues(form.getProperty2());
      for (final InvalidValue invalidValue : property2InvalidValues)
         errors.rejectValue("property2." + invalidValue.getPropertyPath(), invalidValue.getMessage(), invalidValue.getMessage());
      }
   }
}

しかし、フィールド"property2."の値を拒否するときは、値のパスに文字列を追加する必要がありました。property2誰かがもっと良い方法を知っていれば、私はそれを知ってうれしいです。ありがとう

于 2012-11-14T06:36:05.193 に答える