La possibilité de paramétrage du groupement de ressources de Bean Validation dans JSF 2?

L’utilisation du groupe de ressources avec BV dans JSF 2 ressemblerait à ceci:

public class UserBean { @Size(min=13, message="{creditcard.length}") public Ssortingng getCreditCard() { return this.creditCard; } } 

Et je dois définir l’entrée ResourceBundle dans l’un des fichiers de propriétés pouvant être enregistrés dans le faces-config.xml

creditcard.length = la longueur de la carte de crédit doit comporter au moins 13 caractères

Nous pouvons voir que la valeur de creditcard.length n’est pas paramétrée.

Puis-je créer une entrée ResourceBundle paramétrée pouvant être renseignée à partir de BV ou peut-être ailleurs?


C’est un scénario simple que je voudrais réaliser:

creditcard.length = La longueur de la carte de crédit doit comporter au moins {0} caractères. merci d’avoir choisi la carte de crédit {1}.

Et j’espérais quelque chose comme ça:

 public class UserBean { @Size( min=13, message="{creditcard.length}", messageParams={"13", "plantvszombie"}) public Ssortingng getCreditCard() { return this.creditCard; } } 

Et le message d’erreur pour la propriété creditcard affichera une chaîne comme celle-ci lorsque la validation échoue:

la longueur de la carte de crédit doit comporter au moins 13 caractères. merci d’avoir choisi la carte de crédit plantvszombie .


Ce paramétrage du message ResourceBundle est-il possible?

S’il vous plaît partagez votre expérience sur cette question.

Je vous remercie !

Vous savez peut-être déjà que les messages pour la validation de bean sont définis dans le groupe de ressources ValidationMessages.properties à la racine de vos classes (par exemple, WEB-INF\classes\ValidationMessages.properties ).

Ces messages peuvent avoir des parameters mais ils ne fonctionnent pas comme dans JSF. Il existe une interface appelée MessageInterpolator qui transforme le modèle de message en message réel.

L’interpolateur par défaut fonctionne avec des parameters nommés, comme dans le message: La valeur doit être comprise entre {min} et {max} . Les valeurs entre { et } sont d’abord résolues dans le groupe de ressources de l’application. plus tard dans le groupe de ressources du fournisseur et en dernier lieu dans les propriétés de l’annotation de contrainte. (C’est plus ou moins la façon dont cela fonctionne, l’algorithme complet est dans la section 4.3 de la spécification de validation de bean).

Supposons que vous définissiez le message d’atsortingbut de l’annotation Size comme {creditCard.message}

Le contenu de ValidationMessage.properties pourrait être

 creditCard.message=Credit card length must be at least {min} characters. \ Thank you for choosing the plantsvszombies credit card. 

Vous pouvez remplacer plantsvszombies par une propriété:

 creditCard.message=Credit card length must be at least {min} characters. \ Thank you for choosing the {creditCard.type} credit card. creditCard.type=plantsvszombies 

Vous pouvez même utiliser deux parameters dans le message de la contrainte

 Size(min=13, message="{creditCard.message} {plantsvszombies.messages}") 

et définir le groupe de ressources comme

 creditCard.message=Credit card length must be at least {min} characters. plantsvszombies.message=Thank you for choosing the plantsvszombies credit card. 

Je pense que c’est une approche simple et propre.


Mais si vous souhaitez quelque chose de plus similaire à la définition de parameters personnalisés dans la déclaration de la contrainte, vous pouvez utiliser un interpolateur de message personnalisé. S’il vous plaît noter que cela pourrait être une solution plus délicate .

Eh bien, vous pouvez définir une syntaxe pour introduire vos parameters dans la chaîne de message. Ensuite, laissez l’interpolateur par défaut résoudre le message. La syntaxe des parameters personnalisés ne sera pas comprise par l’interpolateur par défaut et ils seront toujours là après la résolution. Ensuite, l’interpolateur personnalisé peut remplacer remplacer les parameters personnalisés.

C’est plus facile à comprendre avec un exemple.

Tout d’abord, un message est défini comme {creditCard.message} [plantsvszombies] . Pour cette syntaxe, le contenu entre les crochets est constitué des parameters indexés séparés par des virgules (il n’ya qu’un paramètre).

Ensuite, le contenu du groupe de ressources est défini avec:

  creditCard.message=Credit card length must be at least {min} characters. \ Thank you for choosing the {0} credit card. 

Lorsque l’interpolateur par défaut remplace la première partie de l’expression, nous avons:

La longueur de la carte de crédit doit comporter au moins 13 caractères. \ Merci d’avoir choisi la carte de crédit {0}. [Plantsvszombies]

Ensuite, l’interpolateur personnalisé prendra la dernière expression et divisera le contenu pour obtenir les jetons et remplacera les parameters indexés par le jeton de l’index correspondant (paramètre [0] = plantsvzzombies).

Le message sera donc:

La longueur de la carte de crédit doit comporter au moins 13 caractères. \ Merci d’avoir choisi la carte de crédit plantsvszombies.

C’est le code de l’interpolateur personnalisé pour cette syntaxe (non optimisé et le motif d’expression régulière pourrait ne pas fonctionner s’il existe d’autres crochets dans la première expression ou dans les jetons).

  package validation; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.validation.MessageInterpolator; import javax.validation.Validation; public class MyInterpolator implements MessageInterpolator{ private MessageInterpolator interpolator; public MyInterpolator() { //we need to delegate to the default interpolator this.interpolator = Validation.byDefaultProvider().configure().getDefaultMessageInterpolator(); } private static final Pattern parametersPattern=Pattern.comstack("\\[(.+)\\]$"); protected static Ssortingng replaceParameters(Ssortingng message){ Matcher matcher = parametersPattern.matcher(message); Ssortingng values[]={}; if(matcher.find()){ values=matcher.group(1).split("\\s*,\\s*"); message=message.subssortingng(0, matcher.start()); for(int i=0; i < values.length; i++){ message=message.replace("{"+i+"}", values[i]); } } return message; } @Override public String interpolate(String messageTemplate, Context context) { String message = interpolator.interpolate(messageTemplate, context); return replaceParameters(message); } @Override public String interpolate(String messageTemplate, Context context, Locale locale) { String message = interpolator.interpolate(messageTemplate, context); return replaceParameters(message); } } 

L'enregistrement de l'interpolateur se fait dans le fichier XML appelé META-INF / validation.xml (4.4.6 de la spécification).

   validation.MyInterpolator  

C'est une solution un peu compliquée car les annotations de contrainte n'acceptent pas les parameters des messages et parce que dans l'interpolateur, nous ne pouvons pas obtenir beaucoup d'informations sur la propriété en cours de validation. Si je trouve une solution plus facile, je la posterai.