2017-01-09 15 views
1

にフィールドの値を使用して、私は次のアノテーションクラスJavaの注釈:別のフィールド

public @interface Size { 
    int min() default 1; 
    int max() default 100; 
    String message() default "Age between min - max"; 
} 

を持ってここでデフォルトmessage()で私はmin()max()のデフォルト値が欲しいです。 String message() default "Age between" + min() + "-" + max();と書くだけではここでは動作しません。それを行う直接的な方法はありますか?

EDIT 1:私は今、あまりにも

public class Person { 

    @Size(max = 10) 
    private String name; 

    @Size(min = 18, message = "Age can not be less than {min}") 
    private int age; 

    public Person(String s, int i) { 
    this.name = s; 
    this.age = i; 
    } 
} 

人のクラスを持っている 、ここでmin()max()値を設定することができます。したがって、ユーザが間違った入力をした場合、message()はそれに応じてプリンタになります。

EDIT 2: as @nicolas wanted。ここでは入力を検証し、エラーメッセージを出力するAnnonatedValidatorクラスです。

public class AnnotatedValidator { 

public static void validate(Person p, List<ValidationError> errors) { 

    try { 
     Field[] fields = p.getClass().getDeclaredFields(); 
     for(Field field : fields) { 
      if(field.getType().equals(String.class)){ 
       field.setAccessible(true); 
       String string = (String)field.get(p); 

       Annotation[] annotationsName = field.getDeclaredAnnotations(); 
       for (Annotation annotation : annotationsName){ 
        if (annotation instanceof Size){ 
         Size size = (Size) annotation; 
         if (string.length() < size.min() || string.length() > size.max()) { 
          error(size, errors); 
         } 
        } 
       } 

      } else if (field.getType().equals(int.class)) { 
       field.setAccessible(true); 
       int integer = (Integer)field.get(p); 

       Annotation[] annotationsAge = field.getDeclaredAnnotations(); 
       for (Annotation annotation : annotationsAge){ 
        if (annotation instanceof Size){ 
         Size size = (Size) annotation; 
         if (integer < size.min() || integer > size.max()) { 
          error(size,errors); 
         } 
        } 
       } 
      } 
     } 

    }catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
} 

public static void print(List<ValidationError> errors) { 
    for (int i = 0; i < errors.size(); i++){ 
     System.out.println("Errors: " + errors.get(i).getError()); 
    } 
} 

public static void error (Size size, List<ValidationError> errors) { 
    String error = size.message(); 
    if (!error.equals(null)) { 
     if (error.contains("min")) { 
      error = error.replace("min", ""+size.min()); 
     } 
     if (error.contains("max")){ 
      error = error.replace("max", ""+size.max()); 
     } 
    } 

    ValidationError v = new ValidationError(); 
    v.setError(error); 
    errors.add(v); 
} 
} 

ValidationErrorはエラーを保存する別のクラスです。

+1

注釈値が一定でなければならない、あなたはすでに – AdamSkywalker

+1

を呼び出すことはできません期待される結果を得るために入力を改善したい場合にはメッセージを表示するコード –

+0

表示を説明するように定数のみがデフォルト値として期待されているので、あなたは、むしろメッセージを出力しますコードでそれを管理する必要がある最小/最大 –

答えて

3

いいえ、defaultの値Stringのタイプは、Java Language Specification dictatesのように定数式でなければなりません。

エレメントタイプが、エレメント値を持つ に相応しない場合、コンパイル時エラーです。

  • Tは配列型ではなく、Vのタイプがある[...]

    • :要素タイプTは、次のいずれかに該当する場合にのみ 要素値Vに見合いましたT、およびと割り当て互換 (5.2):
      • [...]
      • Tがプリミティブ型またはStringある場合、T hen Vは定数式です(§15.28)。
  • 別のアノテーション要素の呼び出しは定数式ではありません。

    注釈の使用を管理するコンポーネントでこれを処理する必要があります。 defaultメッセージを特別な値として宣言します。

    String message() default "REPLACE_ME"; 
    

    メッセージを作成するときに確認します。例えば

    Field field = ... // get 'age' field 
    Size size = field.getAnnotation(Size.class); 
    if (size != null) { 
        String message = size.message(); 
        if (message.equals("REPLACE_ME")) { 
         message = "Age between " + size.min() + " - " + size.max() + "."; 
        } 
    } 
    int min = size.min(); 
    int max = size.max(); 
    // if field is of type int 
    int value = field.getInt(instance); 
    if (value > max || value < min) { 
        throw new ConstraintViolationException(message); 
    } 
    
    +0

    Yah、私はまた、デフォルトのメッセージをmin()とmax()の値に置き換えることでこの問題を解決しました。 @NicolasFilottoが言及したように動的に実行できるかどうかは疑問です。 –

    関連する問題