消息包中的enuma标签

时间:2013-08-30 08:38:27

标签: java jsf web-applications enums

我有一个enum,其中包含selectOneMenu的一些条目,这意味着枚举结构如下所示:display, pdfLabel

我想从消息包中加载条目标签,这意味着区域设置上的取决于

它运行正常,但这是我解开项目后的第一次。这意味着,如果区域设置是“en”我第一次加载条目,即使在注销 - 会话无效之后;如果我将语言环境更改为“de”,则条目仍然来自“en” - 消息。它只在我重新部署时才有效。

有人对这种行为有所了解吗?

我的枚举:

public enum Transportmittel {
     TRUCK(I18n.get("tv.moc.truck"), "TRUCK"), 
     AIRFREIGHT(I18n.get("tv.moc.airfreight"), "AIRFREIGHT"), 
     TRAIN(I18n.get("tv.moc.train"), "TRAIN"), 
     SEAFREIGHT(I18n.get("tv.moc.seafreight"), "SEAFREIGHT"), 
     BARGE(I18n.get("tv.moc.barge"), "BARGE");

String ausgabe;
String pdfLabel;

private Transportmittel(String ausgabe, String pdfLabel) {
    this.ausgabe = ausgabe;
    this.pdfLabel = pdfLabel;
}

public String toString() {
    return ausgabe;
}

public String getLabelForPdf() {
    return pdfLabel;
}

}

我加载条目的控制器:

@PostConstruct
public void init() {
    transportMittelSelectList.add(new SelectItem(Transportmittel.TRUCK.pdfLabel, Transportmittel.TRUCK.ausgabe));
    transportMittelSelectList.add(new SelectItem(Transportmittel.TRAIN.pdfLabel, Transportmittel.TRAIN.ausgabe));
    transportMittelSelectList.add(new SelectItem(Transportmittel.AIRFREIGHT.pdfLabel, Transportmittel.AIRFREIGHT.ausgabe));
    transportMittelSelectList.add(new SelectItem(Transportmittel.SEAFREIGHT.pdfLabel, Transportmittel.SEAFREIGHT.ausgabe));
    transportMittelSelectList.add(new SelectItem(Transportmittel.BARGE.pdfLabel, Transportmittel.BARGE.ausgabe));
}

这是我加载消息包的地方:

public class I18n {

    public static String get(String msg) {
        FacesContext context = FacesContext.getCurrentInstance();
        ResourceBundle bundle = context.getApplication().getResourceBundle(
                                context, "messages");
        return bundle.getString(msg);
    }
}

2 个答案:

答案 0 :(得分:2)

枚举值为static - 因此,当通过类加载器加载类时,它们的构造函数只被调用一次(=第一次使用)。因此,在连续使用时,您仍然会在第一次使用时使用包含在构造时设置的相同字符串ausgabe的相同实例。

因此,您必须在使用时设置ausgabepdfLabel的值。但也许最好有一些“外部”类知道如何获取枚举值的不同标签,而不是让这些值以某种方式在枚举中进行硬编码。

答案 1 :(得分:1)

这确实无法奏效。在整个应用范围内,枚举属性只初始化一次,而i18n基本上应该按照请求进行解析。

您需要重新设计枚举,只保留标签键而不是已解析的本地化值。

TRUCK("tv.moc.truck", "TRUCK"), 
AIRFREIGHT("tv.moc.airfreight", "AIRFREIGHT"), 
TRAIN("tv.moc.train", "TRAIN"), 
SEAFREIGHT("tv.moc.seafreight", "SEAFREIGHT"), 
BARGE("tv.moc.barge", "BARGE");

然后在应用程序作用域bean中提供如下的枚举值:

@ManagedBean
@ApplicationScoped
public class Data {

    public Transportmittel[] getTransportmittels() {
        return Transportmittel.values();
    }

}

然后在<f:selectItems>中引用它,如下所示(看,不需要SelectItem样板文件):

<f:selectItems value="#{data.transportmittels}" var="transportmittel"
    itemValue="#{transportmittel}" itemLabel="#{bundle[transportmittel.ausgabe]}" />

或者,如果您恰好使用了JSF实用程序库OmniFaces,正如您的用户配置文件中当前所示,那么您也可以绕过整个应用程序范围的Data bean和import它直接在EL范围内如下:

<o:importConstants type="com.example.Transportmittels" /> <!-- can be declared in a master template -->
...
<f:selectItems value="#{Transportmittels}" var="transportmittel"
    itemValue="#{transportmittel}" itemLabel="#{bundle[transportmittel.ausgabe]}" />

另见: