2016-06-10 52 views
1

是否可以訪問字段值,其中的字段名稱在描述類中另一個字段的註釋中描述。如何訪問註釋屬性中描述的字段

例如:

@Entity 
public class User { 

    @NotBlank 
    private String password; 

    @Match(field = "password") 
    private String passwordConfirmation; 
} 

譯註:

@Target(ElementType.FIELD) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = FieldMatchValidator.class) 
@Documented 
public @interface Match { 

    String message() default "{}"; 

    Class<?>[] groups() default {}; 

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

    String field(); 
} 

現在,是有可能從類用戶訪問現場密碼ConstraintValidator implementaion類?


編輯:

我寫了這樣的事情:

public class MatchValidator implements ConstraintValidator<Match, Object> { 

private String mainField; 
private String secondField; 
private Class clazz; 

@Override 
public void initialize(final Match match) { 
    clazz = User.class; 

    final Field[] fields = clazz.getDeclaredFields(); 
    for (Field field : fields) { 
     if (field.isAnnotationPresent(Match.class)) { 
      mainField = field.getName(); 
     } 
    } 

    secondField = match.field(); 
} 

@Override 
public boolean isValid(final Object value, final ConstraintValidatorContext constraintValidatorContext) { 
    try { 
     Object o; //Now how to get the User entity instance? 

     final Object firstObj = BeanUtils.getProperty(o, mainField); 
     final Object secondObj = BeanUtils.getProperty(o, secondField); 

     return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj); 
    } catch (final Exception ignore) { 
     ignore.printStackTrace(); 
    } 
    return true; 
} 
} 

現在的問題是如何才能得到用戶對象實例和比較字段的值?

+0

的[?是否可以讀取Java中的註解的值(http://stackoverflow.com/q/4296910/2078908) – ursa

+0

@ursa感謝提示可能的複製,幫助我很多。但現在我被困在另一個問題上,請參閱編輯。 – zach

+0

@zach你有沒有這個物體? 'isValid'方法的參數'value'。 – Jesper

回答

1

你要麼需要編寫一個class level constraint在你傳入用戶實例的IsValid通話,也可以使用類似@ScriptAssert

目前無法訪問root bean實例作爲「常規」字段驗證的一部分。有一個BVAL問題 - BVAL-237 - 討論增加這個功能,但到目前爲止它還不是Bean驗證規範的一部分。

請注意,爲什麼root bean無法訪問atm有很好的理由。依賴於可訪問的根bean的約束將失敗的情況下的驗證值的情況。

+0

你說我需要編寫類級約束,是否有可能使用'@ Entity'類級別註釋來代替寫入新的註解? – zach

+1

不確定你使用@Entity的意思,但答案是否定的。您需要編寫自己的客戶類級別約束。 – Hardy

0

@Hardy Thenks for tip。最後寫了一些符合(或多或少)預期結果的代碼。

我會粘貼在這裏,也許會幫助別人解決他的問題。

@Target(ElementType.FIELD) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
public @interface Match { 

    String field(); 

    String message() default ""; 
} 

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = MatchValidator.class) 
@Documented 
public @interface EnableMatchConstraint { 

    String message() default "Fields must match!"; 

    Class<?>[] groups() default {}; 

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

public class MatchValidator implements ConstraintValidator<EnableMatchConstraint, Object> { 

    @Override 
    public void initialize(final EnableMatchConstraint constraint) {} 

    @Override 
    public boolean isValid(final Object o, final ConstraintValidatorContext context) { 
     boolean result = true; 
     try { 
      String mainField, secondField, message; 
      Object firstObj, secondObj; 

      final Class<?> clazz = o.getClass(); 
      final Field[] fields = clazz.getDeclaredFields(); 

      for (Field field : fields) { 
       if (field.isAnnotationPresent(Match.class)) { 
        mainField = field.getName(); 
        secondField = field.getAnnotation(Match.class).field(); 
        message = field.getAnnotation(Match.class).message(); 

        if (message == null || "".equals(message)) 
         message = "Fields " + mainField + " and " + secondField + " must match!"; 

        firstObj = BeanUtils.getProperty(o, mainField); 
        secondObj = BeanUtils.getProperty(o, secondField); 

        result = firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj); 
        if (!result) { 
         context.disableDefaultConstraintViolation(); 
         context.buildConstraintViolationWithTemplate(message).addPropertyNode(mainField).addConstraintViolation(); 
         break; 
        } 
       } 
      } 
     } catch (final Exception e) { 
      // ignore 
      //e.printStackTrace(); 
     } 
     return result; 
    } 
} 

以及如何使用它...?就像這樣:

@Entity 
@EnableMatchConstraint 
public class User { 

    @NotBlank 
    private String password; 

    @Match(field = "password") 
    private String passwordConfirmation; 
} 
相關問題