问题描述
我有一个faces-config.xml
文件,其中声明了一些资源束,如下所示:
I have a faces-config.xml
file with some resource bundles declared, like this:
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>de</supported-locale>
<supported-locale>es</supported-locale>
<supported-locale>pt</supported-locale>
<supported-locale>zh</supported-locale>
</locale-config>
<resource-bundle>
<base-name>messages.Messages</base-name>
<var>bundle</var>
</resource-bundle>
<resource-bundle>
<base-name>countries.Countries</base-name>
<var>countryBundle</var>
</resource-bundle>
</application>
</faces-config>
这些资源束已注册并且可以在任何.xhtml
文件中使用,但是有什么方法可以以编程方式注册这些资源束?我的意思是使用动态代码而不是xml
声明.
These resource bundles are registered and can be used in any .xhtml
file, but is there any way to register these resource bundles programmatically? I mean by the use of dynamic code instead of a xml
declaration.
推荐答案
以下是我使用CDI所做的简化版本:
Here's a simplified version of what I'm doing using CDI:
@ApplicationScoped
public class BundleProducer {
@Produce @RequestScoped @Named
public ResourceBundle getMsgBundle() {
Locale userLocale = Faces.getLocale();
return ResourceBundle.getBundle("messages", userLocale);
}
}
请注意使用omnifaces的 getLocale()可以避免大量的锅炉代码(对于较不健全的版本,可以像链接到的教程中那样替换FacesContext.getCurrentInstance().getViewRoot().getLocale()
.)
Note the use of omnifaces' getLocale() to avoid a ton of boilerplace code (for a less sane version, you can substitute FacesContext.getCurrentInstance().getViewRoot().getLocale()
like in the tutorial you linked to).
由于 @ Named 批注.在这种简单情况下,我依靠ResourceBundle
内部缓存和查找机制来有效地产生我的包.只要您从方法返回ResourceBundle
(不允许返回null
),就可以执行此处喜欢的任何逻辑(例如,从封闭的BundleProducer
中加载内容).
This will cause the CDI framework to call getMsgBundle
once each request if it needs to access to msgBundle
thanks to the @Named annotation. In this simple case, I'm relying on the ResourceBundle
internal caching and lookup mechanisms to produce my bundle efficiently. You can execute any logic you like here (eg, load stuff from the enclosing BundleProducer
) as long as you return a ResourceBundle
from the method (you're not allowed to return null
).
使用更多产生不同束的方法随意重复.
Repeat as you like with more methods producing different bundles.
不确定我是否明白您的要求,因此,如果需要更多说明,请发表评论.
Not sure if I got what you were after, so just comment if you need more clarification.
为了更轻松地处理FacesMessage
内容,我建议您看看omnifaces的消息实用程序类.我使用类似这样的东西来能够有选择地将捆绑密钥作为消息字符串提供:
For easier handling of FacesMessage
stuff, I'd recommend having a look at omnifaces' Messages utility class. I use something like this to be able to optionally give bundle keys as message strings:
@Singleton
@Startup
public class MessageResolverInit {
@PostConstruct
public void initMessageResolver() {
Messages.setResolver(new Messages.Resolver() {
@Override
public String getMessage(String message, Object... params) {
Locale userLocale = Faces.getLocale();
ResourceBundle b = ResourceBundle.getBundle("msgs", userLocale);
if (b.containsKey(message)) {
return MessageFormat.format(b.getString(message), params);
}
return message;
}
});
}
请注意,我仅将b
作为变量名用于演示.用法如下:
Note that I use b
as a variable name only for demo purposes. Usage goes like this:
Messages.addGlobalError("my_msg_key", param1);
Messages.addGlobalInfo("I'm a standalone message");
这篇关于以编程方式添加资源包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!