Java 枚举消息包中的标签
我有一个Java 枚举消息包中的标签,java,jsf,web-applications,enums,Java,Jsf,Web Applications,Enums,我有一个enum,其中有一些条目用于selectOneMenu,这意味着enum结构如下所示:display,pdfLabel 我想从我的消息包中加载条目标签,这意味着取决于区域设置 它工作得很好,但只是在我完成项目后的第一次。这意味着,如果在我第一次加载条目时区域设置为“en”,即使在注销-会话无效之后;如果我将区域设置更改为“de”,则条目仍然来自“en”-消息。只有在我重新部署的情况下它才会起作用 有人知道这种行为吗 我的枚举: public enum Transportmittel {
enum
,其中有一些条目用于selectOneMenu
,这意味着enum结构如下所示: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);
}
}
枚举值是
静态的
——因此当类加载器加载类时(=第一次使用)只调用它们的构造函数一次。因此,在连续使用时,您仍然使用同一实例,该实例包含在第一次使用期间构造时设置的相同字符串ausgabe
因此,使用时必须设置
ausgabe
和pdfLabel
的值。但是,如果有一些“外部”类知道如何为枚举值获取不同的标签,而不是让这些值以某种方式硬编码在枚举中,那可能更好。这确实行不通。枚举属性仅在应用程序范围内初始化一次,而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();
}
}
然后在
中引用它,如下所示(看,不需要SelectItem
样板文件):
或者,如果您碰巧已经使用了JSF实用程序库,如您的用户配置文件中当前所示,那么您也可以绕过整个应用程序范围的数据bean,直接在EL范围内使用它,如下所示:
...
另见:
您能告诉我们i18n的xml配置吗?以及如何准确地切换区域设置。@没有人可以添加它,但我很确定这与我的问题无关,因为消息包中的所有其他值都会相应地加载。正如下面的答案所解释的,我认为它必须与enum做更多的工作。无论如何,谢谢你的帮助:)是的,你是对的,枚举值是静态的,很好。然而,我想到了这个解决方案:反正我只支持两种语言,所以我只是将它们添加到我的enumausgabe_de,ausgabe_en
,然后根据语言环境将它们加载到我的列表中。你对此有什么看法?我认为这不是个好主意。如果有另一种语言支持(例如奥地利方言;),会发生什么情况。如前所述,我将介绍另一个类,它为您提供特定枚举值的国际化字符串。因此,您只需调用EnumLabel.getLabel(enumValue)
,并根据当前区域设置返回正确的标签。要查找枚举值的对应标签,您可以在枚举值中存储消息键,也可以使用枚举的名称(或FQN)来完成此操作。一如既往,非常感谢您的帮助。