2011-12-15 4 views
1

Est-il possible d'annoter une méthode Java de telle sorte que je puisse donner plus tard une autre méthode à un identificateur de champ ou quelque chose comme ça, afin que cette méthode puisse appeler la bonne?Annoter Méthodes pour les choisir plus tard

Je sais que normalement vous le feriez avec des interfaces, mais dans mon cas ce serait un immense nombre d'interfaces ... Je dois utiliser cela dans les classes Entity pour ma base de données (et je ne suis pas autorisé à utiliser un ORM Mapper)

par exemple: J'ai l'entité

public class Account{ 
    private String username; 
    private String password; 
    private String name; 
    private String mail; 


    public void setUserName(String username){ 
     this.username = username; 
    } 

    public String getUserName(){ 
     return username; 
    } 

    [all other getter/Setter...] 
} 

maintenant, je veux dire une méthode qu'il a besoin de valider un champ, par exemple le champ username.

La méthode qui ne devrait ressembler à ceci:

public void validateField(XXX Field, Entity entity) throws ValidationFailedException, EmptyFieldException; 

XXX est en quelque sorte le FieldIdentifier.

Est-ce possible en Java?

Mon seul suppose que ce que j'utilise public static final ìnt choses là-dedans pour donner tous les domaines d'une méthode ou si ...

Répondre

3

Qu'est-ce que vous utilisez? Je ne vois aucune annotation à partir de laquelle je peux deviner votre cadre. Si vous utilisez Hibernate, vous pouvez utiliser quelque chose comme @NotNull ou autre chose, ou même faire votre validation personnalisée: Voici comment vous aller avec votre exemple:

public class Account{ 

    @NotNull(message="This field should not be null") 
    private String username; 
    @NotBlank(message="This string should not be empty or null") 
    private String password; 
    private String name; 
    private String mail; 


    public void setUserName(String username){ 
     this.username = username; 
    } 

    public String getUserName(){ 
     return username; 
    } 

    [all other getter/Setter...] 
} 

http://silentwalker.wordpress.com/2009/04/07/custom-validation-in-hibernate/

Vous pouvez également créer vos propres annotations sans utiliser de cadre et utilisez-les @prepersist ou quoi que ce soit. Fondamentalement, le ciel est la limite.

P.S Puisque vous ne voulez pas utiliser un code non interne, voici comment vous pouvez aborder:

D'abord, vous pouvez définir une annotation

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface NotNull{ 
    public String message() default ""; 
} 

Puis, avant de persister la classe, vous inspecter son champs:

Alors, vous avez quelque chose comme ceci:

Field[] classFields = yourObjectPrePersist.getClass().getDeclaredFields(); 
for (int i = 0; i < classFields.length; i++) { 
     classFields[i].setAccessible(true);//take notice that if you use a SecurityManager, you should work around it 
     if (classFields[i].getAnnotation(NotNull.class) != null) { 
      Object value = classFields[i].get(yourObjectPrePersist); 
      //here check if value is null or not and then return the message 
      if (value == null) { 
       throw new SomeException(((NotNull) classFields[i].getAnnotation(NotNull.class)).message()); 
      } 
     } 
    } 
+0

oui nous avons besoin excectly, mais nous ne sommes pas autorisés à utiliser un ORM .. Nous devons écrire cela à partir de zéro:/ – reox

+0

Vous pouvez facilement écrire votre propre annotation au niveau du champ. Je vais poster un exemple. –

+0

oui oui oui: o awesome³ :) – reox

0

Les annotations ne semblent pas comme la bonne solution au problème que vous décrivez.

Une possibilité serait de passer au nom du champ qui doit être validé, puis utilisé la classe java.beans.BeanInfo pour accéder aux valeurs de champ de l'entité. Cela vous permettra d'accéder à des attributs arbitraires d'un objet sans avoir à gérer toute la complexité de la réflexion.

0

Vous pouvez utiliser la réflexion pour cela; voir the documentation for java.lang.reflect.Field. L'appelant peut passer le nom de champ sous forme de chaîne, et validateField peut utiliser quelque chose comme Field f = entity.getClass().getField(fieldName).

Mais ce n'est généralement pas une bonne idée. . . la réflexion est géniale, mais elle nécessite beaucoup de code standard, et vous payez un prix élevé en maintenabilité. (Vous payez également une pénalité de performance, bien que dans mon expérience la pénalité de maintenabilité soit bien pire que la pénalité de performance.) Personnellement j'utilise beaucoup la réflexion dans le code de test (ça peut aider à écrire des tests extrêmement complets) et j'utilise des frameworks comme Spring et Hibernate qui dépendent de la réflexion, mais je l'évite dans mon propre code de production.

0

vous pouvez utiliser une interface générique

 
public interface Field { 
    public String getValue(); 
} 

et appelez votre méthode validate avec des classes de Anonymouse

 
validator.validate(new Field() { 
    return account.getUsername() 
}); 

(ou avec vieux java)

 
validator.validate(new Field() { 
    public String getValue() { 
     return account.getUsername(); 
    } 
}); 

Sinon, à quoi l'utilisation java.lang.Methode directement?

PS: Désolé pour la citation, stackoverflow ne me laisse pas poster mon texte directement, a dit qu'il n'a pas été formaté correctement: -/

Questions connexes