我的JSF应用程序中的i18n枚举有问题。开始时,我有枚举,其中包含定义的文本。但是现在,我有一些键绑定到枚举中的消息包。我的枚举示例之一: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; }}在视图层中,我使用类似:<!-- input --><h:selectOneMenu value="#{order.status}"> <f:selectItems value="#{flowUtils.orderStatuses}"/></h:selectOneMenu><!-- output --><h:outputText value="#{order.status}"/>在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); }}它工作得很好,但是当我需要输出#{order.status}时,我需要对其进行转换。因此,我实现了一个转换器,但是在String方法中将Object转换为getAsObject()时遇到了麻烦。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; }}我现在对此很纠结。有人知道如何有效地使多个枚举国际化吗? 最佳答案 通过转换器传递的值不是您期望的选项标签,而是选项值。最佳实践是不要在模型端执行此操作,而应该在视图端执行此操作,因为模型不需要知道i18n。对于这种方法,您基本上不必要地使事情复杂化。从JSF 1.2开始,有一个内置的EnumConverter会自动启动,并且从JSF 2.0开始,您可以通过新的List属性在通用数组或f:selectItems中的var上进行迭代,而无需在在模型中。Bean的外观如下所示:public class Bean { private OrderStatus orderStatus; private OrderStatus[] orderStatuses = OrderStatus.values(); // ...}这是视图的外观(假设List<SelectItem>指的是msg在<var>中的<resource-bundle>中定义的faces-config.xml):<h:selectOneMenu value="#{bean.orderStatus}"> <f:selectItems value="#{bean.orderStatuses}" var="orderStatus" itemValue="#{orderStatus}" itemLabel="#{msg[orderStatus.name]}" /></h:selectOneMenu>就这样。与此问题无关,您在枚举名称和消息键中输入了错别字,应该是:PENDING("enum.orderstatus.pending"),CANCELLED("enum.orderstatus.cancelled");而且,更干净的方法是将捆绑密钥保留在枚举之外,并将枚举本身用作捆绑密钥的一部分。例如。PENDING,CANCELLED;<h:selectOneMenu value="#{bean.orderStatus}"> <f:selectItems value="#{bean.orderStatuses}" var="orderStatus" itemValue="#{orderStatus}" itemLabel="#{msg['enum.orderstatus.' += orderStatus]}" /></h:selectOneMenu>enum.orderstatus.PENDING = Pendingenum.orderstatus.CANCELLED = Cancelled关于jsf-2 - 在资源束中本地化枚举值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4375578/
10-11 17:07