Чтение свойств пакета ресурсов в управляемом bean
Используя <resource-bundle>
файлы, я могу иметь текст i18n на своих страницах JSF.
Но можно ли получить доступ к этим же свойствам в моем управляемом bean, чтобы я мог устанавливать сообщения лиц с значениями i18n?
Ответы
Ответ 1
Предполагая, что вы настроили его следующим образом:
<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);
// ...
}
Вы даже можете получить его стандартным API ResourceBundle
так же, как сам JSF уже работает под обложками, вам нужно будет только повторить базовое имя в коде:
public void someAction() {
FacesContext context = FacesContext.getCurrentInstance();
ResourceBundle text = ResourceBundle.getBundle("com.example.i18n.text", context.getViewRoot().getLocale());
String someKey = text.getString("some.key");
// ...
}
Или, если вы управляете beans CDI вместо JSF, вы можете создать @Producer
для этого:
public class BundleProducer {
@Produces
public PropertyResourceBundle getBundle() {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().evaluateExpressionGet(context, "#{text}", PropertyResourceBundle.class);
}
}
И введите его, как показано ниже:
@Inject
private PropertyResourceBundle text;
В качестве альтернативы, если вы используете класс Messages
библиотеки служебных программ JSF OmniFaces, вы можете просто установить свой резольвер один раз, чтобы все методы 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 и демонстрационная страница.
Ответ 2
Другая возможность:
лица-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");
Ответ 3
Вот решение, которое я использую, не так просто, но по крайней мере работает:
Первый класс:
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");
Если у вас есть вопросы, не стесняйтесь!
EDIT:
Вам также необходимо объявить 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>