JSF/Converters

Cette page a été rédigée il y a fort fort longtemps, et n'a pas tellement été mise à jour.

 

Vous savez, moi je ne crois pas qu'il y ait de bonne ou de mauvaise page. Moi, si je devais résumer mon wiki aujourd'hui avec vous, je dirais que c'est d'abord des rencontres. Des gens qui m'ont tendu la main, peut-être à un moment où je ne pouvais pas, où j'étais seul chez moi. Et c'est assez curieux de se dire que les hasards, les rencontres forgent une destinée... Parce que quand on a le goût de la chose, quand on a le goût de la chose bien faite, le beau geste, parfois on ne trouve pas l'interlocuteur en face je dirais, le miroir qui vous aide à avancer. Alors ça n'est pas mon cas, comme je disais là, puisque moi au contraire, j'ai pu ; et je dis merci au wiki, je lui dis merci, je chante le wiki, je danse le wiki... je ne suis qu'amour ! Et finalement, quand des gens me disent « Mais comment fais-tu pour avoir cette humanité ? », je leur réponds très simplement que c'est ce goût de l'amour, ce goût donc qui m'a poussé aujourd'hui à entreprendre une construction logicielle... mais demain qui sait ? Peut-être simplement à me mettre au service de la communauté, à faire le don, le don de soi.

Les données affichées dans une page JSF possèdent deux représentations :

  • Côté client (code HTML), elles existent sous la forme de chaînes de caractères

  • Côté serveur (dans les backing beans), les données peuvent en revanche être typées (entier, date…​)

Il est donc nécessaire de pouvoir convertir ces données depuis le modèle Java vers le modèle HTML (composants d’affichage et de saisie) et réciproquement (cela concerne les composants de saisie lors du submit d’un formulaire).

Convertisseurs standards

JSF est livré avec un ensemble de convertisseurs standards.

Convertir une valeur numérique

Le NumberConverter

Ce convertisseur donne la possibilité de convertir des numériques suivant trois types différents : number (type par défaut), currency ou percent (et non pas percentage comme indiqué dans certaine documentation). En fonction du type retenu, on peut appliquer un formatage particulier, comme par exemple :

  • Affichage d’un prix

<h:inputText value="#{produitBean.prix}">
  <f:convertNumber type="currency"
                   groupingUsed="true"
                   currencyCode="EUR"
                   currencySymbol="€"
                   maxIntegerDigits="5"
                   maxFractionDigits="2"/>
</h:inputText>
  • Affichage d’un pourcentage

<h:outputText value="#{produitBean.tva}">
  <f:convertNumber type="percent"
                   minFractionDigits="1"
                   maxFractionDigits="1"/>
</h:outputText>

Remarque : dans le cas de composants de saisie, ce convertisseur ne fonctionne qu’avec les types double et long. Pour les autres types (float, int, short…​), il faut utiliser le tag <f:converter>

Autres convertisseurs numériques

En lecture seule (composants d’affichage tel que <h:outputText/>), les types int,short et float étant compatibles avec les types long et double, il est possible d’utiliser le tag <f:convertNumber/>. En revanche, une IllegalArgumentException est levée avec les composants de saisie, car le ConvertNumber génère un long si la valeur saisie est un entier, et un double si la valeur saisie est un réel. Ces valeurs ne peuvent donc pas être injectées dans des variables dont les types sont de moindre précision (int, short, float). Il convient donc d’utiliser un autre converter dans ce cas. Il existe plusieurs possibilités pour utiliser le convertisseur souhaité :

  • Attribut converter

<h:inputText value="#{produitBean.quantite}"
             converter="javax.faces.convert.IntegerConverter" />
  • Tag <f:converter/>

<h:inputText value="#{produitBean.quantite}"
             converter="Integer" />

Cette solution nécessite d’incrire le convertisseur dans le fichier de configuration JSF :

<converter>
  <converter-id>Integer</converter-id>
  <converter-class>javax.faces.convert.IntegerConverter</converter-class>
</converter>

Convertisseurs personnalisés

Il est possible d’étendre l’API afin d’ajouter ses propres convertisseurs.