如何从托管 bean 中获取消息包字符串?
Posted
技术标签:
【中文标题】如何从托管 bean 中获取消息包字符串?【英文标题】:How can I get a message bundle string from inside a managed bean? 【发布时间】:2011-09-10 12:07:07 【问题描述】:我希望能够从 JSF 2 托管 bean 内部的消息包中检索字符串。这将在字符串用作FacesMessage
中的摘要或详细信息参数或用作抛出异常中的消息的情况下完成。
我想确保托管 bean 为用户的语言环境加载正确的消息包。我不清楚如何使用 JSF API 调用从托管 bean 执行此操作。
我的配置是:
使用 Tomcat 7 作为容器,因此解决方案不能依赖仅在完整应用服务器容器中工作的 API 调用 使用 JSF 2 参考实现 (Mojarra) 不使用任何允许 CDI 的库注意:我确实看到了this similar question,但这取决于我的配置中不可用的功能
编辑:我在最初的问题中犯了一个错误。我想问的是“如何从托管 bean 中获取 resource 捆绑字符串”? BalusC 给出了我所问的正确答案。我真正想问的解决方案非常相似:
public static String getResourceBundleString(
String resourceBundleName,
String resourceBundleKey)
throws MissingResourceException
FacesContext facesContext = FacesContext.getCurrentInstance();
ResourceBundle bundle =
facesContext.getApplication().getResourceBundle(
facesContext, resourceBundleName);
return bundle.getString(resourceBundleKey);
另外,这里有一个指向another question 的链接,它解释了“消息”包和“资源”包之间的区别。
【问题讨论】:
【参考方案1】:您可以通过Application#getMessageBundle()
获取<message-bundle>
的完整限定包名称。您可以通过UIViewRoot#getLocale()
获取当前语言环境。您可以从完全合格的捆绑包中获得ResourceBundle
ResourceBundle#getBundle()
的名称和语言环境。
所以,总结一下:
FacesContext facesContext = FacesContext.getCurrentInstance();
String messageBundleName = facesContext.getApplication().getMessageBundle();
Locale locale = facesContext.getViewRoot().getLocale();
ResourceBundle bundle = ResourceBundle.getBundle(messageBundleName, locale);
// ...
更新:根据问题中的错误,您实际上想要获取由<resource-bundle>
的<base-name>
标识的捆绑包。不幸的是,标准的 JSF API 不能直接使用它。您可以在代码中硬编码相同的基本名称并将上面示例中的 messageBundleName
替换为它,或者将其作为托管属性注入到请求范围 bean 中的 <var>
上:
@ManagedProperty("#msg")
private ResourceBundle bundle; // +setter
【讨论】:
我刚试过这个,但messageBundleName
被设置为 null,这会导致在对 getBundle()
的调用中出现 NullPointerException
。
我的错误。我对资源包和消息包感到困惑。请参阅我对原始问题的编辑。
后一种解决方案不起作用。它为 bundle 报告 NullPointerException。
@Emerald:完全遵循问题和答案中提供的信息时,对我和其他任何人都有效。如果您仍然无法弄清楚,只需按 [] 按钮,而不是用误导性和无信息的“不起作用”cmets 污染有效答案。
@BalusC 这仅适用于英语和德语的消息包,但不适用于保加利亚语。你知道为什么吗?【参考方案2】:
FacesContext context = FacesContext.getCurrentInstance();
ResourceBundle bundle = context.getApplication().getResourceBundle(context, "msg");
String message = bundle.getString("key");
这里的关键是您要从属性文件中访问的属性名称。
message = This is "message"
此条目来自 messages.properites 文件。而“消息”是“关键”。
【讨论】:
确实这就像一个魅力。我确实想知道为什么您需要将上下文指定为参数。 "msg" 是 faces config 中定义的变量【参考方案3】:有两种方法可以在托管 bean 中获取 String 资源包,使用 baseName
或 varName
(请参阅下面的每个定义):
使用 varName:
varName
: 是代表<resource-bundle>
中<var></var>
的字符串
FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
ResourceBundle bundle = app.getResourceBundle(context, varName);
String msg = bundle.getString("key");
使用 baseName:
baseName
:资源包的完全限定名称(<resource-bundle>
中的<base-name>
)。
FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context .getViewRoot().getLocale();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, loader);
String msg = bundle.getString("key");
【讨论】:
不正确。ResourceBundle#getBundle()
将基本名称作为第一个参数。也许你很困惑,因为你给了它们两个相同的值。
@BalusC 我在代码中混淆了 varName 和 baseName,但我更正了,感谢您的通知以上是关于如何从托管 bean 中获取消息包字符串?的主要内容,如果未能解决你的问题,请参考以下文章
如何从过滤器中获取 SessionScoped CDI bean?