Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

jsf - Injecting ResourceBundle via @ManagedProperty doesn't seem to work inside @Named

How can I access messages bundle from java code to get message according to current locale?

I tried using @ManagedProperty like below:

@Named 
@SessionScoped 
public class UserBean implements Serializable {

    @ManagedProperty("#{msg}")
    private ResourceBundle bundle;

    // ...

    public void setBundle(ResourceBundle bundle) {
        this.bundle = bundle;
    }

}

However, it remains null. It seems that it doesn't work inside a @Named.

This is how I registered the resource bundle in faces-context.xml:

<application>

    <message-bundle>validator.messages</message-bundle>

    <locale-config>
        <supported-locale>en_US</supported-locale>
        <supported-locale>ua_UA</supported-locale>
    </locale-config>

    <resource-bundle>
        <base-name>lang.messages</base-name>
        <var>msg</var>
    </resource-bundle>

</application>

udated by author:

@BalusC I get error

16:29:10,968 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/WEBSearchPrime_JB_lang].[Faces Servlet]] (http-localhost-127.0.0.1-8080-1) Servlet.service() for servlet Faces Servlet threw exception: org.jboss.weld.exceptions.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\n\nProducer: Producer Method [PropertyResourceBundle] with qualifiers [@Any @Default] declared as [[method] @Produces public util.BundleProducer.getBundle()]\nInjection Point: [field] @Inject private model.UserBean.bundle

note, that I also put Serializable interface

See Question&Answers more detail:os

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

1 Answer

0 votes
by (71.8m points)

You can't use @javax.faces.bean.ManagedProperty in a CDI managed bean as annotated with @Named. You can only use it in a JSF managed bean as annotated with @ManagedBean.

You need use @javax.faces.annotation.ManagedProperty instead, along with an @Inject. This was introduced in JSF 2.3.

@Inject @javax.faces.annotation.ManagedProperty("#{msg}")
private ResourceBundle bundle;

Noted should be that this gets injected as a @Dependent. So be aware that when you inject this into a @SessionScoped bean, then it would basically become @SessionScoped too and thus stick to the originally injected value forever. So any potential locale changes later on in the session won't be reflected there. If this is a blocker, then you should really inject it into a @RequestScoped or @ViewScoped only, or make use of a @Producer as shown below.

CDI doesn't have native annotations to inject the evaluation result of an EL expression. The CDI approach is using a "CDI producer" with @Produces wherein you return the concrete type, which is PropertyResourceBundle in case of .properties file based resource bundles.

So, if you cannot upgrade to JSF 2.3, then just drop this class somewhere in your WAR:

@RequestScoped
public class BundleProducer {

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

}

With this, can inject it as below:

@Inject
private PropertyResourceBundle bundle;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...