本文介绍了JSF 2本地化(托管Bean)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于本地化的属性文件:

I have a properties file for localization:

foo=Bar
title=Widget Application

这是在faces-config中作为resource-bundle绑定的:

This is tied in as a resource-bundle in the faces-config:

<resource-bundle>
    <base-name>com.example.messages.messages</base-name>
    <var>msgs</var>
</resource-bundle>

我可以使用EL在facelets视图中很好地访问它:

I can access this just fine in the facelets view using EL:

<title>#{msgs.title}</title>

但是,如果有类似SQLExceptions的东西,我需要能够从托管bean写入消息.这一切都可以:

However, if there are things like SQLExceptions, I need to be able to write messages from the managed bean. This is all working also:

FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "There was an error saving this widget.", null);
FacesContext.getCurrentInstance().addMessage(null, message);

这是问题所在:我希望这些消息来自属性文件,以便它们也可以根据语言环境进行更改.有没有一种简单的方法可以使用注入来访问属性文件?

Here is the issue: I want to have those messages come from the properties file so that they, too, can be changed based on the locale. Is there an easy way to access the properties file using injection?

推荐答案

我在SO上问了一个非常相关的问题:如何注入非具有Weld的可序列化类(例如java.util.ResourceBundle)

I asked a quite related question on SO:How to inject a non-serializable class (like java.util.ResourceBundle) with Weld

在Seam论坛中: http://seamframework.org/Community/HowToCreateAnInjectableResourcebundleWithWeld

And inside the Seam Forum:http://seamframework.org/Community/HowToCreateAnInjectableResourcebundleWithWeld

总结一下:我实现了由3个生产者组成的可注射ResourceBundle.首先,您需要一个FacesContextProducer.我从Seam 3 Alpha来源中拿了一个.

To summarize:I realized an injectable ResourceBundle with 3 Producers.First you need a FacesContextProducer. I took the one from the Seam 3 Alpha sources.

public class FacesContextProducer {
   @Produces @RequestScoped
   public FacesContext getFacesContext() {
      FacesContext ctx = FacesContext.getCurrentInstance();
      if (ctx == null)
         throw new ContextNotActiveException("FacesContext is not active");
      return ctx;
   }
}

然后,您需要一个使用FacesContextProducer的LocaleProducer.我也是从Seam 3 Alpha那里拿来的.

Then you need a LocaleProducer, which uses the FacesContextProducer. I also took it from Seam 3 Alpha.

public class FacesLocaleResolver {
   @Inject
   FacesContext facesContext;

   public boolean isActive() {
      return (facesContext != null) && (facesContext.getCurrentPhaseId() != null);
   }

   @Produces @Faces
   public Locale getLocale() {
      if (facesContext.getViewRoot() != null)
         return facesContext.getViewRoot().getLocale();
      else
         return facesContext.getApplication().getViewHandler().calculateLocale(facesContext);
   }
}

现在您已拥有创建ResourceBundleProducer的所有功能,该外观如下所示:

Now you have everything to create a ResourceBundleProducer, which can look like this:

public class ResourceBundleProducer {
  @Inject
  public Locale locale;

  @Inject
  public FacesContext facesContext;

  @Produces
  public ResourceBundle getResourceBundle() {
   return ResourceBundle.getBundle("/messages", facesContext.getViewRoot().getLocale() );
  }
}

现在,您可以@将ResourceBundle注入到bean中.请注意,必须将其注入到瞬时属性中,否则您将收到一个异常,抱怨ResourceBundle无法序列化.

Now you can @Inject the ResourceBundle into your beans. Pay attention that it has to be injected into a transient attribute, otherwise you'll get an exception complaining that ResourceBundle is not serializable.

@Named
public class MyBean {
  @Inject
  private transient ResourceBundle bundle;

  public void testMethod() {
    bundle.getString("SPECIFIC_BUNDLE_KEY");
  }
}

这篇关于JSF 2本地化(托管Bean)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-02 18:24