1

我有 aenum的一些条目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);
    }
}
4

2 回答 2

2

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

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

于 2013-08-30T09:04:30.687 回答
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,如当前在您的用户配置文件中所示,那么您也可以绕过整个应用程序范围的Databean 并将其直接导入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]}" />

也可以看看:

于 2013-08-30T12:00:58.323 回答