再次讨论了before以及我想要分享“我的”解决方案并要求增强,其他方法或最佳实践的内容。
我有几个需要国际化的枚举(我需要将枚举值翻译成某些语言,以便在jsf页面中显示它们)。考试枚举:
public enum TransferStatus {
NOT_TRANSFERRED,
TRANSFERRED
}
翻译可以是Not yet transferred
/ Transferred, all good
翻译应存储在MessageBundle(属性文件)中。我正在寻找一个简单,通用的解决方案(最好不需要在所有枚举中编写额外的代码),这在jsf方面并不需要太多。只是要提一下,当然有两个不同的枚举可能会使用相同的枚举值(例如COMPLETED
之类的值在不同的枚举中具有不同的含义)。
我提出的解决方案:
(1)将翻译存储在属性文件中,如下所示:
TransferStatus.NOT_TRANSFERRED = Not yet transferred
TransferStatus.TRANSFERRED = Transferred, all good
(2)创建一个带有枚举的helper类并生成查找键:
public class EnumTranslator {
public static String getMessageKey(Enum<?> e) {
return e.getClass().getSimpleName() + '.' + e.name();
}
}
(3)将此代码添加到每个枚举:
public String getKey() {
return EnumTranslator.getMessageKey(this);
}
(4)现在,我可以像这样访问我的枚举的翻译值:
<h:outputText value="#{enum[order.transferStatus.key]}" />
哪个没关系,但我不喜欢的是为每个枚举添加相同的getKey()
方法。应该有更好的东西!现在轮到你了,SO: - )
答案 0 :(得分:3)
好的,现在这是一个完整的,随时可用的解决方案:(感谢@Joop Eggen)
上课
public final class EnumTranslator {
public static String getMessageKey(Enum<?> e) {
return e.getClass().getSimpleName() + '.' + e.name();
}
}
使其成为自定义EL功能
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://example.com/enumi18n</namespace>
<function>
<function-name>xlate</function-name>
<function-class>your.package.EnumTranslator</function-class>
<function-signature>String getMessageKey(java.lang.Enum)</function-signature>
</function>
</facelet-taglib>
将taglib添加到您的web.xml
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/enumi18n.taglib.xml</param-value>
</context-param>
拥有像这样的属性文件enum_en.properties和enum_yourlanguage.properties
TransferStatus.NOT_TRANSFERRED = Not transferred
TransferStatus.TRANSFERRED = Transferred
将属性文件作为资源包添加到faces-config.xml
<resource-bundle>
<base-name>kk.os.obj.jsf.i18n.enum</base-name>
<var>enum</var>
</resource-bundle>
将自定义taglib添加到xhtml文件
<html ... xmlns:l="http://example.com/enumi18n">
并且 - vo - - 您现在可以在jsf中访问已翻译的枚举值:
<h:outputText value="#{enum[l:xlate(order.transferStatus)]}" />
答案 1 :(得分:1)
我会创建一个EL函数,保留枚举类:
#{l:xlate(order.transferStatus)}
好的,xlate有一个Object参数(或Enum<?>
)。但是enum课程保持不变。
答案 2 :(得分:1)
我这样做的方式需要更多的代码(但远远低于我在这里看到的其他答案),但我觉得更可靠:
@ManagedBean
@ApplicationScoped
public class EnumTranslator {
private <E extends Enum<E>> Map<E, String> getPresentableNames(Class<E> enumClass) {
ResourceBundle resources = ResourceBundle.getBundle(
"com.example.app.MyMessageBundle",
FacesContext.getCurrentInstance().getViewRoot().getLocale());
String prefix = enumClass.getSimpleName() + ".";
Map<E, String> map = new EnumMap<E, String>(enumClass);
for (E value : enumClass.getEnumConstants()) {
map.put(value, resources.getString(prefix + value));
}
return map;
}
// Bean method, accessible via EL
public Map<?, ?> getTransferStatuses() {
return getPresentableNames(TransferStatus.class);
}
}
然后您的页面可以执行:
<h:outputText value="#{enumTranslator.transferStatuses[order.transferStatus]}" />
答案 3 :(得分:1)
怎么样:
public interface InternationalizationOfEnum {
default String getKey() {
return EnumTranslator.getMessageKey(this);
}
String name();}
和
public enum anyEnum implements InternationalizationOfEnum{