Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
818 views
in Technique[技术] by (71.8m points)

jsf - Read resource bundle properties in a managed bean

Using <resource-bundle> files I'm able to have i18n text in my JSF pages.

But is it possible to access these same properties in my managed bean so I can set faces messages with i18n values?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Assuming that you've configured it as follows:

<resource-bundle>
    <base-name>com.example.i18n.text</base-name>
    <var>text</var>
</resource-bundle>

If your bean is request scoped, you can just inject the <resource-bundle> as @ManagedProperty by its <var>:

@ManagedProperty("#{text}")
private ResourceBundle text;

public void someAction() {
    String someKey = text.getString("some.key");
    // ... 
}

Or if you just need some specific key:

@ManagedProperty("#{text['some.key']}")
private String someKey;

public void someAction() {
    // ... 
}

If your bean is however in a broader scope, then evaluate #{text} programmatically in method local scope:

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    ResourceBundle text = context.getApplication().evaluateExpressionGet(context, "#{text}", ResourceBundle.class);
    String someKey = text.getString("some.key");
    // ... 
}

Or if you only need some specific key:

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    String someKey = context.getApplication().evaluateExpressionGet(context, "#{text['some.key']}", String.class);
    // ... 
}

You can even just get it by the standard ResourceBundle API the same way as JSF itself is already doing under the covers, you'd only need to repeat the base name in code:

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    ResourceBundle text = ResourceBundle.getBundle("com.example.i18n.text", context.getViewRoot().getLocale());
    String someKey = text.getString("some.key");
    // ... 
}

Or if you're managing beans by CDI instead of JSF, then you can create a @Producer for that:

public class BundleProducer {

    @Produces
    public PropertyResourceBundle getBundle() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{text}", PropertyResourceBundle.class);
    }

}

And inject it as below:

@Inject
private PropertyResourceBundle text;

Alternatively, if you're using the Messages class of the JSF utility library OmniFaces, then you can just set its resolver once to let all Message methods utilize the bundle.

Messages.setResolver(new Messages.Resolver() {
    public String getMessage(String message, Object... params) {
        ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", Faces.getLocale());
        if (bundle.containsKey(message)) {
            message = bundle.getString(message);
        }
        return MessageFormat.format(message, params);
    }
});

See also the example in the javadoc and the showcase page.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...