2

繰り返しになりますが、以前に話し合ったことがあり、「自分の」ソリューションを共有して、機能強化、他のアプローチ、またはベストプラクティスを求めたいと思っていました。

国際化が必要な列挙型がいくつかあります(jsfページに表示するには、列挙型の値をいくつかの言語に変換する必要があります)。列挙型の例:

public enum TransferStatus {
  NOT_TRANSFERRED,
  TRANSFERRED
}

翻訳は例えばNot yet transferred/Transferred, all good

翻訳はMessageBundle(プロパティファイル)に保存する必要があります。私は、jsf側で多くを必要としない、簡単で一般的なソリューション(すべての列挙型に追加のコードを記述する必要がないことが最善です)を探していました。言うまでもなく、もちろん、2つの異なる列挙型が同じ列挙型の値を共有する可能性があります(たとえば、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()すべての列挙型に同じメソッドを追加することです。それよりも良いものがあるはずです!今度はあなたの番です、SO :-)

4

4 に答える 4

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">

そして--voilà--jsfで変換された列挙値にアクセスできるようになりました:

<h:outputText value="#{enum[l:xlate(order.transferStatus)]}" />
于 2013-03-26T10:07:09.377 に答える
1

列挙型クラスをそのままにして、EL関数を作成します。

#{l:xlate(order.transferStatus)}

さて、xlateにはObjectパラメータがあります(またはEnum<?>)。ただし、列挙型クラスはそのままです。

于 2013-03-26T09:20:13.120 に答える
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]}" />
于 2013-03-26T10:29:51.120 に答える
1

どうですか:

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

public enum anyEnum implements InternationalizationOfEnum{
于 2015-10-15T14:57:34.557 に答える