2010-04-18 8 views
8

Je cherche à utiliser Hibernate Validator pour une exigence du mien. Je veux valider un JavaBean où les propriétés peuvent avoir plusieurs contrôles de validation. Par exemple:Générer un code d'erreur par propriété dans Hibernate Validator

class MyValidationBean 
{ 
    @NotNull 
    @Length(min = 5, max = 10) 
    private String myProperty; 
} 

Mais si cette propriété validation échoue Je veux un code d'erreur spécifique à associer à la ConstraintViolation, indépendamment du fait que il a échoué à cause de @Required ou @Length, bien que je voudrais préserver l'erreur message.

class MyValidationBean 
{ 
    @NotNull 
    @Length(min = 5, max = 10) 
    @ErrorCode("1234") 
    private String myProperty; 
} 

Quelque chose comme ce qui précède serait bon, mais il n'a pas besoin d'être structuré exactement comme ça. Je ne peux pas voir un moyen de le faire avec Hibernate Validator. C'est possible?

Répondre

0

Dans la section 4.2. ConstraintViolation de la spécification:

La méthode getMessageTemplate renvoie le message d'erreur non interpolé (généralement l'attribut message sur la déclaration de contrainte). Les cadres peuvent l'utiliser comme clé de code d'erreur.

Je pense que c'est votre meilleure option.

+1

Merci pour la réponse. Malheureusement, je ne pense pas que cela conservera le message d'erreur original, ce que je voudrais. Je suis à la recherche d'un code d'erreur supplémentaire en plus de cela. Malheureusement, en regardant l'API pour ConstraintViolation, je ne vois vraiment rien de prometteur. –

0

Ce que j'essaierais d'isoler ce comportement sur le calque DAO de l'application.

En utilisant votre exemple, nous aurions:

public class MyValidationBeanDAO { 
    public void persist(MyValidationBean element) throws DAOException{ 
     Set<ConstraintViolation> constraintViolations = validator.validate(element); 
     if(!constraintViolations.isEmpty()){ 
      throw new DAOException("1234", contraintViolations); 
     } 
     // it's ok, just persist it 
     session.saveOrUpdate(element); 
    } 
} 

Et la classe d'exception suivante:

public class DAOException extends Exception { 
private final String errorCode; 
private final Set<ConstraintViolation> constraintViolations; 

public DAOException(String errorCode, Set<ConstraintViolation> constraintViolations){ 
    super(String.format("Errorcode %s", errorCode)); 
    this.errorCode = errorCode; 
    this.constraintViolations = constraintViolations; 
} 
// getters for properties here 
} 

Vous pouvez ajouter des informations d'annotation basée sur ce que la propriété n'a pas validé d'ici, mais toujours faire ceci sur la méthode DAO.

J'espère que cela a aidé.

4

Vous pouvez créer une annotation personnalisée pour obtenir le comportement que vous recherchez, puis, en validant et en utilisant refelection, vous pouvez extraire la valeur de l'annotation. Quelque chose comme ce qui suit:

@Target({ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface ErrorCode { 
    String value(); 
} 

Dans votre haricot:

@NotNull 
@Length(min = 5, max = 10) 
@ErrorCode("1234") 
public String myProperty; 

sur la validation de votre haricot:

Set<ConstraintViolation<MyValidationBean>> constraintViolations = validator.validate(myValidationBean);  
for (ConstraintViolation<MyValidationBean>cv: constraintViolations) { 
    ErrorCode errorCode = cv.getRootBeanClass().getField(cv.getPropertyPath().toString()).getAnnotation(ErrorCode.class); 
    System.out.println("ErrorCode:" + errorCode.value()); 
} 

Cela dit que je serais probablement en question les exigences de vouloir les codes d'erreur pour ces types de messages.

+0

Ceci est une excellente solution merci de poster. Juste une chose à noter ... Le code devrait lire getDeclaredField pour lui permettre d'accéder au champ privé. – MandyW