Как я могу получить строку пакета сообщений из управляемого компонента?
Я хотел бы иметь возможность получить строку из пакета сообщений внутри управляемого компонента JSF 2. Это будет сделано в ситуациях, когда строка используется в качестве сводного или подробного параметра в FacesMessage
или как сообщение в брошенном исключении.
Я хочу убедиться, что управляемый компонент загружает правильный пакет сообщений для локали пользователя. Мне не понятно, как это сделать из управляемого компонента с помощью вызовов API JSF.
Моя конфигурация:
- Использование Tomcat 7 в качестве контейнера, поэтому решение не может зависеть от вызовов API, которые работают только в полном контейнере сервера приложений
- Использование эталонной реализации JSF 2 (Mojarra)
- НЕ использовать библиотеки, которые позволяют CDI
ПРИМЕЧАНИЕ: я видел этот похожий вопрос, но это зависит от функций, которые недоступны в моей конфигурации
РЕДАКТИРОВАТЬ: я сделал ошибку в моем первоначальном вопросе. Я хотел спросить: "Как я могу получить строку комплекта ресурсов внутри управляемого компонента"? BalusC дал мне правильный ответ на то, что я спросил. Решение, о котором я действительно хотел спросить, очень похоже:
public static String getResourceBundleString(
String resourceBundleName,
String resourceBundleKey)
throws MissingResourceException {
FacesContext facesContext = FacesContext.getCurrentInstance();
ResourceBundle bundle =
facesContext.getApplication().getResourceBundle(
facesContext, resourceBundleName);
return bundle.getString(resourceBundleKey);
}
Кроме того, здесь есть ссылка на другой вопрос, который объясняет разницу между пакетами "сообщения" и пакетами "ресурса".
3 ответа
Вы можете получить полное квалифицированное имя пакета <message-bundle>
от Application#getMessageBundle()
, Вы можете получить текущую локаль по UIViewRoot#getLocale()
, Вы можете получить ResourceBundle
из полного квалифицированного имени пакета и локали ResourceBundle#getBundle()
,
Итак, подведем итог:
FacesContext facesContext = FacesContext.getCurrentInstance();
String messageBundleName = facesContext.getApplication().getMessageBundle();
Locale locale = facesContext.getViewRoot().getLocale();
ResourceBundle bundle = ResourceBundle.getBundle(messageBundleName, locale);
// ...
Обновление: согласно ошибке в вопросе, вы на самом деле хотите получить пакет, который идентифицируется <base-name>
из <resource-bundle>
, К сожалению, это не доступно напрямую стандартным API JSF. Вы должны либо жестко закодировать то же самое базовое имя в коде и заменить messageBundleName
в приведенном выше примере с ним, или внедрить его в качестве управляемого свойства на <var>
в запросе bean-объекта:
@ManagedProperty("#{msg}")
private ResourceBundle bundle; // +setter
FacesContext context = FacesContext.getCurrentInstance();
ResourceBundle bundle = context.getApplication().getResourceBundle(context, "msg");
String message = bundle.getString("key");
здесь ключ - это имя свойства, к которому вы хотите получить доступ из файла свойств.
message = This is "message"
Эта запись из файла messages.properites. и "сообщение" является "ключом" .
Есть два способа получить пакет ресурсов String в управляемом бине, используя baseName
или же varName
(см. определение каждого из них ниже):
Используя varName:
varName
: строка, представляющая <var></var>
в <resource-bundle>
FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
ResourceBundle bundle = app.getResourceBundle(context, varName);
String msg = bundle.getString("key");
Используя baseName:
baseName
: Полное имя пакета ресурсов (<base-name>
в <resource-bundle>
).
FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context .getViewRoot().getLocale();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, loader);
String msg = bundle.getString("key");