【问题标题】:Internationalization of multiple enums (translation of enum values) [duplicate]多个枚举的国际化(枚举值的翻译)[重复]
【发布时间】:2013-03-26 09:03:53
【问题描述】:

再次讨论了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) 制作一个接受枚举并生成查找键的辅助类:

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() 方法。应该有更好的东西!现在轮到你了,所以:-)

【问题讨论】:

  • 您可以将其发布为另一个问题的答案。这样您就会在适当的时候收到其他用户的反馈。
  • 谢谢,已完成并在此处链接。

标签: java jsf internationalization enums


【解决方案1】:

好的,现在这是完整且可立即使用的解决方案:(感谢@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">

而且 - 瞧 - 您现在可以在 jsf 中访问翻译后的枚举值:

<h:outputText value="#{enum[l:xlate(order.transferStatus)]}" />

【讨论】:

  • 美丽、完整的轨迹,“voilà”居于首位。
【解决方案2】:

我会创建一个 EL 函数,让枚举类保持原样:

#{l:xlate(order.transferStatus)}

好的,xlate 有一个 Object 参数(或Enum&lt;?&gt;)。但是枚举类保持原样。

【讨论】:

  • 这简直太棒了。只需要添加自定义函数来调用我的EnumTranslator.getMessageKey()(参见here 怎么做),现在我可以访问翻译后的枚举值,如下所示:&lt;h:outputText value="#{enum[l:xlate(order.transferStatus)]}" /&gt;。杰出的!非常感谢!
【解决方案3】:

我这样做的方式需要更多的代码(但远远少于我在这里看到的其他答案),但我觉得更可靠:

@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]}" />

【讨论】:

  • 我也喜欢这个,你觉得哪个更靠谱?
  • 直接基于实际枚举值,代码更容易追溯。
【解决方案4】:

怎么样:

public interface InternationalizationOfEnum {
default String getKey() {
      return EnumTranslator.getMessageKey(this);
    }
String name();}

public enum anyEnum implements InternationalizationOfEnum{

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 2016-03-05
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多