0

サンプルに従って、DB から JSF アプリケーションのリソース バンドルのロードを実装しようとしています:データベースからロードされた ResourceBundle エントリを使用した JSF の国際化

テストでは、getItSomehow() をコーディングして HashMap を作成し、キー "hello_world" と値 "["+locale+"]"+"hello world" を入力します。

Glassfish3 にデプロイすると、サンプルは正常に動作します。しかし、WebSphere AS 7 を使用すると、初めて jsf ページが正しく表示されます。他のブラウザーで jsf ページを開く (他の優先言語を選択) と、常に最初の実行のロケールで応答が返されます。

デバッグ中に、ResourceBundle.java の実装の違いを発見しました。Glassfish は、JDK1.6 の rt.jar で提供されるこのクラスを使用します。しかし、WebSphereにはjava.util.jar内にこのクラスがあります

ApplicationResourceBundle.getResourceBundle() から呼び出された (WebSphere の) ResourceBundle は、 handleGetBundle() を呼び出し、最後に my.i18n.DbResourceBundle$DBControl.newBundle() を呼び出します。異なるロケールで 2 回目 (およびそれ以降) に呼び出された場合、オーバーライドは呼び出されず、最初のロケール用に作成された同じバンドルが返されます。

質問: WebSphere AS 7.0.07 にデプロイされた内部化可能な jsf Web アプリケーションを、AS の内部を掘り下げたりハッキングしたりせずにコーディングすることは可能ですか?

(環境: Windows XP、WebSphere AS 7.0.0.7、jdk1.6.0_24、jsf 2.1.4)

4

1 に答える 1

0

ResourceBundle の特定の実装を提供できます。

以下は、JSF が ResourceBundle メソッドを呼び出すたびに現在のロケールを取得する例です。

package my.company.jsf.util;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

public class MyBundle extends ResourceBundle {

    private static final Map<Locale, ResourceBundle> RB_CACHE = new HashMap<Locale, ResourceBundle>();
    private static final String BUNDLE_NAME = "my-messages";

    public MyBundle() {
    }

    @Override
    public Enumeration<String> getKeys() {
        ResourceBundle rb = getResourceBundle();
        final Iterator<String> it = rb.keySet().iterator();
        return new Enumeration<String>() {

            @Override
            public boolean hasMoreElements() {
                return it.hasNext();
            }

            @Override
            public String nextElement() {
                return it.next();
            }

        };
    }


    @Override
    protected Object handleGetObject(String key) {
        ResourceBundle rb = getResourceBundle();
        return rb.getObject(key);
    }

    private ResourceBundle getResourceBundle() {
        Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
        ResourceBundle rb = RB_CACHE.get(locale);
        if (rb == null) {
            rb = ResourceBundle.getBundle(BUNDLE_NAME, locale);
            RB_CACHE.put(locale, rb);
        }
        return rb;
    }
}

そして、faces-config.xml に次のように入力します。

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
    <application>
        <resource-bundle>
            <base-name>my.company.jsf.util.MyBundle</base-name>
            <var>MSG</var>
        </resource-bundle>
    </application>
</faces-config>

同じ問題があり、このソリューションは Windows Server 2008、WebSphere AS 7.0.0.19、jdk1.6.0_29、jsf 2.1.5 で機能しました。

于 2012-04-03T14:24:07.153 に答える