Вопрос

У меня есть файл свойств для локализации:

foo=Bar
title=Widget Application

Это связано как resource-bundle На грани конфигурация:

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

Я могу получить доступ к этому просто отлично на просмотре Facelets с использованием EL:

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

Однако, если есть такие вещи, как SQLExceptions, мне нужно иметь возможность писать сообщения из управляемого компонента. Это все работает также:

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

Вот проблема: я хочу иметь эти сообщения из файла свойств, чтобы они тоже могли быть изменены на основе локали. Есть ли простой способ получить доступ к файлу свойств, используя инъекцию?

Это было полезно?

Решение

Я задал довольно связанный вопрос на так:Как ввести несериализуемый класс (например, java.util.resourcebundle) с сварным швом

А внутри форума шва:http://seamframework.org/community/howtocreateAnnjectableresourcebundlewithweld.

Подводя итоги: я понял инъекционную ResourceBundle с 3 производителями. Сначала вам нужен FacescontextProducer. Я взял один из шва 3 альфа-источников.

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. Я также взял его из шов 3 альфа.

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, который может выглядеть так:

public class ResourceBundleProducer {
  @Inject       
  public Locale locale;

  @Inject       
  public FacesContext facesContext;

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

Теперь вы можете @inject ResourceBundle в ваши бобы. Обратите внимание, что он должен быть введен в преходящий атрибут, в противном случае вы получите исключение, жалующееся, что ResourceBundle не является сериализен.

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

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

Другие советы

Легче использовать, например, модуль сообщения о MyFaces Codi!

Вы можете сделать это с JSF в одиночку.

Начните с определения управляемого свойства на вашем бобовом бону. В конфигурации JSF вы можете установить значение управляемого свойства для экспрессии EL, которое ссылается на ваше ресурс.

Я сделал что-то вроде следующего, используя Tomcat 6. Единственное предостережение состоит в том, что вы не можете получить доступ к этому значению с конструктора вашего Backing Bean, поскольку JSF еще не будет инициализирован. Использовать @PostConstruct По методу инициализации, если значение необходимо в начале жизненного цикла бобов.

<managed-bean>
  ...
  <managed-property>
    <property-name>messages</property-name>
    <property-class>java.util.ResourceBundle</property-class>
    <value>#{msgs}</value>
  </managed-property>
  ...
</managed-bean>

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

Это имеет преимущество в том, чтобы сделать ваши методы поддержки бобов менее зависимы от технологии презентации, поэтому ее следует проще проверить. Это также контролирует ваш код из деталей, как имя, приведенное к расслоению.

Некоторые тестирования с использованием Mojarra 2.0.4-B09 показывают небольшое несоответствие при изменении пользователей MANALE MID-сеанса. In-Page EL Spriseions Используйте новый локаль, но в Beaning Bean не дан новой ссылке ResourceBundle. Чтобы сделать его согласованным, вы можете использовать значение свойства компонентов в EL Sepressions, например, использование #{backingBean.messages.greeting} на месте #{msgs.greeting}. Отказ Затем Page El и Beaning Bean всегда будут использовать локаль, которая была активна, когда началась сессия. Если пользователи имел Для переключения локалей середина сеанса и получите новые сообщения, вы можете попробовать сделать предварительную проверку бобовой фасоли и дать ей ссылки на оба сеансовой фасоли, так и для пакета ресурсов.

Вот пример о том, как это сделать:http://www.laliluna.de/articles/javaserver-faces-message-resource-bundle-tutorial.html.

Вы хотите взглянуть на ResourceBundle.getBundle() часть.

Привет, Ларс

Это старый вопрос, но я добавляю еще один способ сделать это. Я искал что-то еще и побежал через это. Способы здесь все казались запутанными для чего-то, что не поражает меня как все это сложно. Играя с блеском, потому что это красиво, если вы спросите меня.

Учитывая файл:

/com/full/package/path/to/messages/errormessages.properties

Внутри файла:

SOME_ERROR_STRING=Your App Just Cratered

Я создаю метод «GetBundle ()», поскольку мне нравится ловить время выполнения и добавить значимое сообщение, поэтому я пойму, откуда он исходит. Не сложно и может помочь, если вы получите прихоти для поиска с файлами свойств по какой-то причине и не все правильно обновляете. Я иногда делаю этот частный, так как иногда есть метод помощника в классе (для меня). Это держит попытку ловить беспорядок из значимого кода.

Использование полного пути к файлу позволяет размещать его где-то, кроме диапазона / каталога по умолчанию, если у вас есть другие идеи на организации.

public/private ResourceBundle getMessageResourceBundle(){
    String messageBundle = "com.full.package.path.to.messages.errormessages";
    ResourceBundle bundle = null;
    try{
        bundle = ResourceBundle.getBundle(messageBundle);
    }catch(MissingResourceException ex){
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                    "Unable to find message bundle in XYZ Class", ex);
        throw ex;
    }

}

public void doSomethingWithBundle(){

    ResourceBundle bundle = getMessageResourceBundle();
    String someString = bundle.getString("SOME_ERROR_STRING");
    ...
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top