web-dev-qa-db-ja.com

管理対象Beanのリソースバンドルプロパティを読み取る

<resource-bundle>ファイルを使用すると、JSFページにi18nテキストを含めることができます。

しかし、マネージドBeanでこれらの同じプロパティにアクセスして、i18n値でfacesメッセージを設定できるようにすることは可能ですか?

13

次のように構成したと仮定します。

<resource-bundle>
    <base-name>com.example.i18n.text</base-name>
    <var>text</var>
</resource-bundle>

Beanがリクエストスコープの場合は、<resource-bundle>@ManagedPropertyとして<var>として注入できます。

@ManagedProperty("#{text}")
private ResourceBundle text;

public void someAction() {
    String someKey = text.getString("some.key");
    // ... 
}

または、特定のキーが必要な場合:

@ManagedProperty("#{text['some.key']}")
private String someKey;

public void someAction() {
    // ... 
}

ただし、Beanのスコープが広い場合は、メソッドローカルスコープでプログラムで#{text}を評価します。

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    ResourceBundle text = context.getApplication().evaluateExpressionGet(context, "#{text}", ResourceBundle.class);
    String someKey = text.getString("some.key");
    // ... 
}

または、特定のキーのみが必要な場合:

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    String someKey = context.getApplication().evaluateExpressionGet(context, "#{text['some.key']}", String.class);
    // ... 
}

JSF自体がすでに裏で行っているのと同じ方法で、標準のResourceBundle AP​​Iで取得することもできます。必要なのは、コードでベース名を繰り返すことだけです。

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    ResourceBundle text = ResourceBundle.getBundle("com.example.i18n.text", context.getViewRoot().getLocale());
    String someKey = text.getString("some.key");
    // ... 
}

または、JSFではなくCDIでBeanを管理している場合は、そのための@Producerを作成できます。

public class BundleProducer {

    @Produces
    public PropertyResourceBundle getBundle() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{text}", PropertyResourceBundle.class);
    }

}

そして、以下のように注入します。

@Inject
private PropertyResourceBundle text;

または、JSFユーティリティライブラリのMessagesクラスを使用している場合 OmniFaces 、リゾルバーを1回設定するだけで、すべてのMessageメソッドがバンドルを利用できるようになります。 。

Messages.setResolver(new Messages.Resolver() {
    public String getMessage(String message, Object... params) {
        ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", Faces.getLocale());
        if (bundle.containsKey(message)) {
            message = bundle.getString(message);
        }
        return MessageFormat.format(message, params);
    }
});

javadoc および ショーケースページ の例も参照してください。

45
BalusC

別の可能性:

faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config ...>
  <application>
    <locale-config>
      <default-locale>de</default-locale>
    </locale-config>
    <resource-bundle>
      <base-name>de.fhb.resources.text.backend</base-name>
      <var>backendText</var>
    </resource-bundle>
  </application>
</faces-config>

YourBean.Java

FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
ResourceBundle backendText = app.getResourceBundle(context, "backendText");
backendText.getString("your.property.key");
2

これが私が使用している解決策です。単純ではありませんが、少なくとも機能しています。

ファーストクラス :

package com.spectotechnologies.website.util;

import Java.util.Locale;
import Java.util.regex.Matcher;
import Java.util.regex.Pattern;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;

/**
 *
 * @author Alexandre Lavoie
 */
public class MessageInterpolator extends ResourceBundleMessageInterpolator
{
    public static final String LANGUAGE_TAG_PATTERN = "\\{[^}]*\\}";

    @Override
    public String interpolate(String p_sMessage, Context p_oContext)
    {
        return super.interpolate(replaceMessages(p_sMessage),p_oContext);
    }

    @Override
    public String interpolate(String p_sMessage, Context p_oContext, Locale p_oLocale)
    {
        StringManager.setLocale(p_oLocale);

        return super.interpolate(replaceMessages(p_sMessage),p_oContext,p_oLocale);
    }

    private String replaceMessages(String p_sMessage)
    {
        Matcher oMatcher;
        String sKey;
        String sReplacement;
        StringBuffer sbTemp = new StringBuffer();

        oMatcher = Pattern.compile(LANGUAGE_TAG_PATTERN).matcher(p_sMessage);
        while(oMatcher.find())
        {
            sKey = oMatcher.group().substring(1,oMatcher.group().length() - 1);

            sReplacement = StringManager.getString(sKey);

            if(!sReplacement.startsWith("???"))
            {
                oMatcher.appendReplacement(sbTemp,sReplacement);
            }
        }

        oMatcher.appendTail(sbTemp);

        return sbTemp.toString();
    }
}

セカンドクラス:

package com.spectotechnologies.website.util;

import com.spectotechnologies.util.BundleManager;
import com.spectotechnologies.util.FacesSessionManager;
import Java.util.Locale;

/**
 * set-up and interface a BundleManager
 * save the bundleManager into the session
 * @author Charles Montigny
 */
public final class StringManager
{
    /** the session name of this class bundle manager */
    public static final String BUNDLE_MANAGER_SESSION_NAME = "StringManager_BundleManager";

    /**  List of ResourceBundle names to load.
     * Will be load in order.
     * The last ones values may overrite the first ones values. */
    private final static String[] BUNDLE_LIST = {
        "com.spectotechnologies.hibernate.validation.resources.ValidationMessages",
        "com.spectotechnologies.website.general.resources.ValidationMessages",
        "com.spectotechnologies.website.general.resources.General"};

    /** bundle manager */
    private static BundleManager m_oBundleManager = null;

    private static BundleManager getBundleManager()
    {
        if(m_oBundleManager == null)
        {
            // get the bundle into the session
            m_oBundleManager = (BundleManager)FacesSessionManager.getObject(BUNDLE_MANAGER_SESSION_NAME);
            if(m_oBundleManager == null)
            {
                // session was empty, load a new one
                m_oBundleManager = new BundleManager();
                for(int iIndex = 0; iIndex < BUNDLE_LIST.length; iIndex++)
                {
                    m_oBundleManager.addBundle(BUNDLE_LIST[iIndex]);
                }
                // add the bundle to the session
                FacesSessionManager.setObject(BUNDLE_MANAGER_SESSION_NAME, m_oBundleManager);
            }
        }
        return m_oBundleManager;
    }

    /**
     * get a string value in the bundle manager by a string key
     * @param p_sKey the string key
     * @return the value of the string key
     */
    public static String getString(String p_sKey)
    {
        return getBundleManager().getStringValue(p_sKey);
    }

    /**
     * set the locale
     * @param p_oLocale the locale to set
     */
    public static void setLocale(Locale p_oLocale)
    {
        getBundleManager().setLocale(p_oLocale);

        // update the session
        FacesSessionManager.setObject(BUNDLE_MANAGER_SESSION_NAME,
                getBundleManager());
    }
}

プロパティファイルでBUNDLE_LISTをオーバーライドする必要がある後。完了したら、次のように使用します。

sMessage = StringManager.getString("website.validation.modifySystem.modified");

ご不明な点がございましたら、お気軽にどうぞ!

編集:

また、MessageInterpolatorを宣言する必要があります

META-INF/validation.xml

<validation-config
    xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration">
    <message-interpolator>com.spectotechnologies.website.util.MessageInterpolator</message-interpolator>
</validation-config>
1