以编程方式添加资源包

以编程方式添加资源包

本文介绍了以编程方式添加资源包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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");

这篇关于以编程方式添加资源包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!