2010-12-01 5 views
10

私はデータベースから値を読み取るJavaクラスとしてリソースバンドルを持っています。私はDBを更新するときに私はバンドルをリロードする必要があるが、私はどのようにわからない。誰でも助けますか?ビューでWebアプリケーションでリソースバンドルをリロードする方法は?

package model.helpers; 
public class Messages_en extends ListResourceBundle { 
     protected Object[][] getContents() { 
      // from DB 
      // ... 
     } 
} 

私は以下のようにバンドルを使用します。

<f:loadBundle basename="model.helpers.Messages" var="m" /> 

答えて

5
ResourceBundle.clearCache();  

OR

Messages_en .clearCache(); 

リソースを再ロードします。このメソッドを呼び出すと、それはバンドルをリフレッシュします

+1

これはどのように正確に役立ちますか? –

+1

うまく動作します。ありがとう:) – marioosh

+1

f:loadBundleを使用する代わりにfaces-config.xmlで定義されたメッセージバンドルがあるときに、リロードが機能しないことに気づきました。誰も知っている理由は? – marioosh

10

これは必ずしも簡単ではありません。

clearCache()を介してResourceBundleをクリアするだけでは、必ずしも望ましい結果が得られるわけではありません。

ResourceBundle.clearCache(Thread.currentThread().getContextClassLoader());

しかしこれはまだfaces-config.xmlファイルで定義されたリソースバンドルを再ロードしません。多くの場合、あなたは、少なくとも、コンテキストクラスローダを使用してクリアしてみてください必要があります。少なくともMojarra JSF 1.2の実装は、リソースバンドルを内部的に内部的にキャッシュします。これは、中に起こる:

FacesContext -> Application -> associate (ApplicationAssociate) -> resourceBundles (Map<String, ApplicationResourceBundle>()) -> resources (Map<Locale, ResourceBundle>) 

それは(一日の終わりに、それは地図でちょうどエントリです)反射を経て、このキャッシュをクリアすることができます、またはあなたがアプリケーションを交換したいかもしれません。どちらもあなたが普通に気楽にやることではありません。

純粋に開発のために、すでにMojarraについての知識を持っているJRebelを使用することができ、おそらく上記のリフレクショントリックを行う可能性があります。

いくつかの実験の後、私はJBoss AS 5/JSF 1.2のトリックを行う次のコードに行きました。あなたのコードをMojarra(サンパッケージをインポート)に結びつけ、リフレクショントリックが使用されているため、アップグレードすると破損する可能性があります。しかし、いずれにせよ、これはコードです:

public static void reloadBundle() { 

    ResourceBundle.clearCache(Thread.currentThread().getContextClassLoader()); 

    ApplicationResourceBundle appBundle = ApplicationAssociate.getCurrentInstance().getResourceBundles().get("your_bundle_name");    
    Map<Locale, ResourceBundle> resources = getFieldValue(appBundle, "resources");   
    resources.clear(); 
} 

@SuppressWarnings("unchecked") 
private static <T> T getFieldValue(Object object, String fieldName) { 
    try { 
     Field field = object.getClass().getDeclaredField(fieldName); 
     field.setAccessible(true); 
     return (T) field.get(object); 
    } catch (Exception e) { 
     return null; 
    }  
} 

(必要に応じてutilのあなた自身の好みの反射でgetFieldValueヘルパーメソッドを交換し、適切な例外とヌルハンドラを振りかける)は

+0

こんにちはarjan、このチークについて知ってうれしかった、私は遊んでいた、GlassFishのためだけに私のために働かなかった、私は両方のビューレベルのリソースバンドルとアプリケーションレベルを使用してみた、どちらもGF envでこの調整を使用して失敗した –

+0

Glassfishそれは?もしそれがV3なら、Mojarraのバージョンはまったく違うので実際にはうまくいかないかもしれないと思います。私はJBoss AS 5プロジェクトで作業していたので、そこでしかテストしませんでしたが、JBoss AS 6では動作しない可能性があります。 –

+0

V3、V3での回避策、システムの起動@usernameでのあなたのコメント –

1
あなたもに回避することができます

反射のいくつかのより多くのラインを使ってモジュール内で溶接し、JSF-のimplクラスをインポートする必要があります。

Class<?> applicationAssociateClass = Class.forName("com.sun.faces.application.ApplicationAssociate"); 
Method getCurrentInstance = applicationAssociateClass.getMethod("getCurrentInstance"); 
Object applicationAssociate = getCurrentInstance.invoke(null); 
Method getResourceBundles = applicationAssociate.getClass().getMethod("getResourceBundles"); 
Map<String, ?> resourceBundles = (Map<String, ?>)getResourceBundles.invoke(applicationAssociate); 
Object appBundle = resourceBundles.get(name); 
Map<Locale, ResourceBundle> resources = getFieldValue(appBundle, "resources"); 
resources.clear(); 

(Wildfly 10でうまく動作します)

+0

これはWildfly 8でうまくいきました。その愚かなキャッシュをクリアしたのは... – VeenarM

関連する問題