2008-09-29 10 views
14

J'étudie une approche basée sur l'annotation pour valider les beans Spring en utilisant spring modules. En this tutorial, les haricots suivants (accesseurs omis) est utilisé comme un exemple:validation basée sur l'annotation basée sur le haricot

public final class User { 

    @NotBlank 
    @Length(max = 80) 
    private String name; 

    @NotBlank 
    @Email 
    @Length(max = 80) 
    private String email; 

    @NotBlank 
    @Length(max = 4000) 
    private String text; 
} 

Le message d'erreur qui est utilisé si une règle de validation particulière désobéi doit suivre ce format:

bean-class.bean-propery[validation-rule]=Validation Error message 

des exemples de la classe ci-dessus comprennent:

User.email[not.blank]=Please enter your e-mail address. 
User.email[email]=Please enter a valid e-mail address. 
User.email[length]=Please enter no more than {2} characters. 

le fait que les clés de message contiennent le nom de classe présente quelques problèmes:

  1. Si la classe est renommé, les clés de message doivent également être changé
  2. Si j'ai une autre classe (par exemple Person) avec une propriété email validée de la même manière que User.email, j'ai besoin de dupliquer les messages, par ex.

    Person.email [not.blank] = Veuillez entrer votre adresse e-mail.
    Person.email [email] = Veuillez entrer une adresse e-mail valide. Person.email [length] = Entrez au maximum {2} caractères.

En fait, les revendications de documentation qui est possible de configurer un message par défaut pour une règle particulière (par exemple @Email) comme ceci:

email=email address is invalid 

Ce message par défaut doit être utilisé si un haricot message spécifique pour la règle ne peut pas être trouvé. Cependant, d'après mon expérience, cela ne fonctionne tout simplement pas.

Un autre mécanisme permettant d'éviter les messages en double consiste à transmettre la clé du message d'erreur à l'annotation de règle. Par exemple, supposons que je l'ai défini le message d'erreur par défaut suivant la règle @Email

badEmail=Email address is invalid 

Ce message doit être utilisé si j'annote la propriété concernée comme ceci:

@Email(errorCode="badEmail") 
private String email; 

Cependant, j'essayé, encore et encore, cela ne semble pas fonctionner. Quelqu'un at-il trouvé un moyen d'éviter la duplication des messages d'erreur lors de l'utilisation de ce cadre de validation?

Répondre

6

J'ai jeté un coup d'oeil au BeanValidator API, et il semblerait que vous souhaitiez essayer la propriété errorCodeConverter.

Vous devez implémenter votre propre ErrorCodeConverter ou utiliser l'une des implémentations fournies?

.... 
<bean id="validator" class="org.springmodules.validation.bean.BeanValidator" 
    p:configurationLoader-ref="configurationLoader" 
    p:errorCodeConverter-ref="errorCodeConverter" /> 

<bean id="errorCodeConverter" class="contact.MyErrorCodeConverter" /> 
.... 

Note: configurationLoader est un autre bean défini dans le fichier XML de configuration utilisé dans le tutoriel

Exemple convertisseur:

package contact; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.springmodules.validation.bean.converter.ErrorCodeConverter; 

public class MyErrorCodeConverter implements ErrorCodeConverter { 

    private Log log = LogFactory.getLog(MyErrorCodeConverter.class); 

    @Override 
    public String convertPropertyErrorCode(String errorCode, Class clazz, String property) { 
     log.error(String.format("Property %s %s %s", errorCode, clazz.getClass().getName(), property)); 
     return errorCode; // <------ use the errorCode only 
    } 

    @Override 
    public String convertGlobalErrorCode(String errorCode, Class clazz) { 
     log.error(String.format("Global %s %s", errorCode, clazz.getClass().getName())); 
     return errorCode; 
    } 
} 

Maintenant, les propriétés doivent travailler:

MyEmailErrorCode=Bad email 

class Foo { 
    @Email(errorCode="MyEmailErrorCode") 
    String email 
} 
+0

Dans la configuration de Spring présentée ci-dessus, qu'est-ce que le bean configurationLoader? –

+0

Salut Don - J'ai téléchargé le code source à partir du site Web tutoriel que vous avez mentionné, et configurationLoader est déjà l'un des beans définis dans leur config xml. Quand je rentre à la maison et regarde le code que j'ai écrit, je peux mettre à jour cette publication. – toolkit

+0

Le bean configurationLoader du tutoriel est de type org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader – toolkit

2

La validation du printemps a un ErrorCod eConverter qui fait cela:

org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter

Lorsque cela est utilisé, le groupe de ressources sera vérifiée pour les codes suivants:

[errorCode.commandBeanName.fieldName , errorCode.fieldName, errorCode.fieldClassName, errorCode]

  • errorCode est le code d'erreur réel de validation, par ex. not.blank, email.
  • commandBeanName est identique au nom de clé du modèle qui fait référence au bean backing de formulaire .
  • fieldName est le nom du champ.
  • fieldClassName est le nom de la classe de champ, par ex. java.lang.String, java.lang.Integer

Ainsi, par exemple, si j'ai un haricot qui est référencé dans le modèle par la touche « FormBean » et le emailAddress de champ de type java.lang.String ne fonctionne pas contenir une adresse e-mail, ce qui provoque l'email errorCode. Le cadre de validation tentera de résoudre les codes de message suivant:

[email.formBean.emailAddress, email.emailAddress, email.java.lang.String, email]

Si le errorCode est remplacé par le errorCode " badEmail » comme ceci:

@Email (errorCode = "badEmail")

les codes des messages que le cadre essayera résolution sera:

[badEmail.formBean.emailAddress, badEmail.emailAddress, badEmail .Java. lang.String, badEmail]

Je suggère de garder le code d'erreur le même. Ainsi, un message peut être utilisé pour tous les champs auxquels errorCode est associé. Si vous avez besoin d'être plus spécifique avec le message pour un certain champ, vous pouvez ajouter un message aux groupes de ressources avec le code errorCode.commandBeanName.field. Ajoutez les haricots suivants dans votre fichier applicationContext.xml

0

<bean id="configurationLoader" 
    class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader" /> 

<!-- Use the error codes as is. Don't convert them to <Bean class name>.<bean field being validated>[errorCode]. -->  
<bean id="errorCodeConverter" 
    class="org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter"/> 

<!-- shortCircuitFieldValidation = true ==> If the first rule fails on a field, no need to check 
    other rules for that field --> 
<bean id="validator" class="org.springmodules.validation.bean.BeanValidator" 
    p:configurationLoader-ref="configurationLoader" 
    p:shortCircuitFieldValidation="true" 
    p:errorCodeConverter-ref="errorCodeConverter"/>