質問

ローカリゼーション用のプロパティファイルがあります。

foo=Bar
title=Widget Application

これはaとして結び付けられています resource-bundle facesconfig:

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

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/howtocreateanininjectableresourcebundlewithweld

要約すると、3人のプロデューサーとの注入可能なリソースバンルに気付きました。まず、facesContextProducerが必要です。 Seam 3 Alphaソースから1つを取りました。

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を使用するローカルプロデューサーが必要です。また、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を作成するすべてのものがあります。これは次のようになります。

public class ResourceBundleProducer {
  @Inject       
  public Locale locale;

  @Inject       
  public FacesContext facesContext;

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

これで、リソースバンドルを豆に入れてもらうことができます。それを一時的な属性に注入する必要があることに注意してください。そうしないと、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を使用して次のようなことをしました。唯一の注意点は、JSFがまだ初期化されていないため、Backing Beanのコンストラクターからこの値にアクセスできないことです。使用する @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を使用した一部のテストは、ユーザーがロケールの中間セッションを変更すると、わずかな矛盾を示します。インページEL式は新しいロケールを使用しますが、バッキングビーンには新しいResourceBundleリファレンスが与えられていません。それを一貫させるために、使用するなど、EL式でBeanプロパティ値を使用できます #{backingBean.messages.greeting} 代わりに #{msgs.greeting}. 。次に、ページELとバッキングビーンは、セッションが開始されたときにアクティブなロケールを常に使用します。ユーザーの場合 持っていました セッションの途中でロケールを切り替えて新しいメッセージを取得するには、リクエストスコープ付きビーンを作成して、セッションビーンとリソースバンドルの両方に参照することができます。

これを行う方法の例は次のとおりです。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()」メソッドを作成して、それがどこから来ているのか理解できます。難しいことではなく、何らかの理由でPropertiesファイルを使用して気まぐれを取得し、すべてを正しく更新しないでください。クラス内のヘルパーメソッドであることがあるので、私は時々プライベートになります(私にとって)。これにより、意味のあるコードからTry Catch Clutterを排除します。

ファイルへのフルパスを使用すると、組織に関する他のアイデアがある場合は、デフォルトの場所/ディレクトリ以外の場所に配置できます。

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