Localisation des valeurs enum dans le regroupement de ressources
J'ai un problème avec i18n les énumérations dans mon application JSF. Quand j'ai commencé, j'ai eu des enums avec le texte défini à l'intérieur. Mais maintenant, j'ai des touches liée à message embarque dans l'enum.
Exemple un de mes énumérations:
public enum OrderStatus implements CustomEnum {
PENDING("enum.orderstatus.pending"),
CANCELED("enum.orderstatus.canceled");
/**
* key in message bundle
*/
private String name;
OrderStatus(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}
Dans la couche de la vue, j'utilise quelque chose comme:
<!-- input -->
<h:selectOneMenu value="#{order.status}">
<f:selectItems value="#{flowUtils.orderStatuses}"/>
</h:selectOneMenu>
<!-- output -->
<h:outputText value="#{order.status}"/>
et en Java:
public class FlowUtils {
public List<SelectItem> getOrderStatuses() {
ArrayList<SelectItem> l = new ArrayList<SelectItem>();
for(OrderStatus c: OrderStatus.values()) {
//before i18n
//l.add(new SelectItem(c, c.getName()));
//after i18n
l.add(new SelectItem(c, FacesUtil.getMessageValue(c.getName())));
}
return l;
}
}
public class FacesUtil {
public static String getMessageValue(String name) {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().getResourceBundle(context, "m").getString(name);
}
}
Il a bien fonctionné, mais quand j'ai eu besoin de sortie #{order.status}
j'avais besoin de le convertir.
J'ai donc mis en place un convertisseur, mais a eu des ennuis avec la conversion de String
à Object
dans le getAsObject()
méthode.
web.xml:
<converter>
<converter-for-class>model.helpers.OrderStatus</converter-for-class>
<converter-class>model.helpers.EnumTypeConverter</converter-class>
</converter>
Java:
public class EnumTypeConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent comp,
String value) throws ConverterException {
//value = localized value :(
Class enumType = comp.getValueBinding("value").getType(context);
return Enum.valueOf(enumType, value);
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object object) throws ConverterException {
if (object == null) {
return null;
}
CustomEnum type = (CustomEnum) object;
ResourceBundle messages = context.getApplication().getResourceBundle(context, "m");
String text = messages.getString(type.getName());
return text;
}
}
Je suis empêtré aujourd'hui. Quelqu'un sait comment internationaliser plusieurs Énumérations de manière efficace?
source d'informationauteur marioosh
Vous devez vous connecter pour publier un commentaire.
La valeur qui est passé à travers le convertisseur n'est pas l'option étiquette, comme vous semblez le penser, mais la valeur de l'option. La meilleure pratique est de ne pas faire cela dans le côté du modèle, mais dans la vue de côté, parce que le modèle n'a pas besoin d'être i18n conscient.
De l'approche, vous êtes essentiellement de surcharger inutilement les choses. Depuis JSF 1.2, il y a un builtin
EnumConverter
qui donnera un coup de pied dans automatiquement et depuis JSF 2.0, vous pouvez effectuer une itération sur un generic array ouList
dansf:selectItems
par la nouvellevar
attribut sans la nécessité de dupliquer les valeurs sur uneList<SelectItem>
dans le modèle.Voici comment le haricot peut ressembler à:
Et voici comment la vue peut ressembler (en supposant que
msg
se réfère à la<var>
comme vous l'avez défini dans<resource-bundle>
dansfaces-config.xml
):C'est tout.
Sans rapport avec le problème, vous avez de fautes de frappe dans le nom enum et les clés de message, il doit être:
Et, plus propre serait de garder le bundle clés de l'enum et l'utilisation d'enum comme faisant partie du bundle clé. E. g.
J'ai posté ma solution ici: L'internationalisation de plusieurs énumérations (traduction de valeurs enum) - mais toujours l'espoir d'amélioration.
EDIT: avec l'aide de @Joop Eggen, nous sommes venus avec une super solution:
MODIFIER à nouveau: complet et prêt-à-utiliser la solution:
Faire une classe
En faire un personnalisé EL fonction
Ajouter la bibliothèque de tags à votre web.xml
Ont des propriétés des fichiers enum_en.propriétés et enum_yourlanguage.les propriétés de ce type
Ajouter les fichiers de propriétés que les ressources de votre faces-config.xml
Ajouter la coutume bibliothèque de tags de vos fichiers xhtml
Et voilà - vous avez maintenant accès à la traduire les valeurs de l'enum dans jsf:
Bien, enum est juste une autre classe. Il n'y a rien qui vous empêche d'ajouter l'analyse et à la conversion de chaîne méthodes qui leur permettront d'analyser et de sortie des paramètres régionaux de messages sensibles.
Peut-être qu'il viole Seule Responsable Principe (n'est ce pas?), mais je crois que faire enum responsable de l'analyse et de revenir aux paramètres régionaux de conscience des valeurs est la bonne chose à faire.
Juste ajouter deux méthodes comme ceci:
J'espère que j'ai le bon code, car je ne suis pas le vérifier avec l'IDE maintenant... Est-ce ce que vous recherchez?
- Je calculer la clé du message de l'enum, comme indiqué ci-dessous; donc pas besoin de maintenir les touches avec des attributs supplémentaires sur l'enum
Puis-je l'utiliser comme ceci
d'avoir configuré un org.springframework.contexte.de soutien.ReloadableResourceBundleMessageSource dans le contexte de l'application
Au cas où quelqu'un est à la recherche d'un utilitaire simple bibliothèque pour gérer enum internationalisation, veuillez jeter un oeil à https://github.com/thiagowolff/litefaces-enum-i18n
L'artefact est également disponible dans Maven Central:
Fondamentalement, vous avez juste besoin d'ajouter de l'artefact de votre projet et de définir les enum clés respectifs à la suite de la décrit le protocole enum conventions de nommage. Les traductions (et aussi les noms de classe CSS) peuvent être récupérées à l'aide du EL fonctions.