2012-11-13 19 views
2

條件驗證對象字段我有一個複雜的對象,它包含兩個UserPropertyForm對象中:通過使用Spring

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
我需要property2驗證只有userType == 2

任何人都可以說,如果我能在使用註解我有UserPropertyForm領域的一個簡單的方法驗證property2

感謝您的任何幫助。

回答

3
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中收集所有錯誤,則需要在您的JSP中使用 <form:errors path="property2.*"/>

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

} 
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."字符串添加到價值的路徑。如果有人知道更好的方法,我會很高興知道它。謝謝

相關問題