我有一个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);
}
}
答案 0 :(得分:2)
枚举值为static
- 因此,当通过类加载器加载类时,它们的构造函数只被调用一次(=第一次使用)。因此,在连续使用时,您仍然会在第一次使用时使用包含在构造时设置的相同字符串ausgabe
的相同实例。
因此,您必须在使用时设置ausgabe
和pdfLabel
的值。但也许最好有一些“外部”类知道如何获取枚举值的不同标签,而不是让这些值以某种方式在枚举中进行硬编码。
答案 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]}" />