JSF 2本地化(托管bean)

Zac*_*ese 7 jsf cdi jsf-2 managed-bean

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

foo=Bar
title=Widget Application
Run Code Online (Sandbox Code Playgroud)

这与resource-bundlefaces-config中的a相关:

<resource-bundle>
    <base-name>com.example.messages.messages</base-name>
    <var>msgs</var>
</resource-bundle>
Run Code Online (Sandbox Code Playgroud)

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

<title>#{msgs.title}</title>
Run Code Online (Sandbox Code Playgroud)

但是,如果有像SQLExceptions这样的东西,我需要能够从托管bean编写消息.这一切都有效:

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

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

Ing*_*her 16

我在SO上问了一个相关的问题: 如何用Weld注入一个不可序列化的类(比如java.util.ResourceBundle)

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

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

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

然后你需要一个LocaleProducer,它使用FacesContextProducer.我也从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);
   }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以创建一个ResourceBundleProducer,它看起来像这样:

public class ResourceBundleProducer {
  @Inject       
  public Locale locale;

  @Inject       
  public FacesContext facesContext;

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

现在你可以@Inject ResourceBundle到你的bean.注意必须将它注入瞬态属性,否则你会得到一个例外,抱怨ResourceBundle不可序列化.

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

  public void testMethod() {
    bundle.getString("SPECIFIC_BUNDLE_KEY");
  }
}
Run Code Online (Sandbox Code Playgroud)