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

你说的曾经没有我的故事 提交于 2019-11-27 07:14:30

问题


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


回答1:


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

CDI doesn't have any annotations to inject the evaluation result of an EL expression like as @ManagedProperty. 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.

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);
    }

}

Now you can inject it as below:

@Inject
private PropertyResourceBundle bundle;



回答2:


In addition to BalusC's answer:

Since JSF 2.3 it is also possible to inject a resource bundle defined in faces-config.xml without the use of a producer method. There is a new annotation javax.faces.annotation.ManagedProperty (note it is in the ...annotation package, not the ...bean package) that works with @Inject:

// ...
import javax.faces.annotation.ManagedProperty;
// ...

@Named 
@SessionScoped 
public class UserBean implements Serializable {

  // ...

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

  // ...

}


来源:https://stackoverflow.com/questions/28045667/injecting-resourcebundle-via-managedproperty-doesnt-seem-to-work-inside-named

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!