Как переопределить некоторые ресурсы из PropertyResourceBundle
-
19-08-2019 - |
Вопрос
У меня есть существующий веб-сайт Java / JSF. Весь текст на экране поступает из файлов свойств через < f: loadBundle basename = " org.example.applicaltion " вар = Quot & & applicaltion Quot; / GT &; который извлекает текст из applicaltion.properties.
Для настраиваемого подмножества во время выполнения я хочу получить строку из другого места (CMS через веб-сервисы). Глядя на класс ResourceBundle, кажется, что есть инфраструктура для чего-то близкого к нему с делегированием родительского ResourceBundle.
Я хочу что-то подобное
public class Applicaltion extends ResourceBundle{
@Override
protected Object handleGetObject(String key) {
if(overridenKey(key)){
return overridedValue(key);
}
return null; // ResourceBundle.getObject will delegate to parent
// if we return null
}
}
Я пробовал это, и parent равен null, я предполагаю, что это больше используется для случая по умолчанию - > en - > en_GB.
Я рассматриваю не очень привлекательный вариант, когда у файла свойств будет другое имя, отличное от пользовательского resourceBundle, и затем делегирование через полный стек ResourceBundle.getBundle (PROPERTY_FILE_NAME) .getString (key) из CustomResourceBundle.handleGetObject (key). . р>
Есть идеи получше?
Решение
В итоге я решил эту проблему, проверив, есть ли у нас значение переопределения, если мы его возвращали, иначе делегирование стандартному пакету ресурсов
public class UILabels extends ResourceBundle {
private ResourceBundle getFileResources(){
return ResourceBundle.getBundle("com.example.web.UILabelsFile", this.getLocale());
}
public Enumeration<String> getKeys() {
return getFileResources().getKeys();
}
protected Object handleGetObject(String key) {
if(overrideValue(key)){
return getOverridenValue(key);
}
return getFileResources().getObject(key);
}
}
Обратите внимание, что небольшим отличием в классе имен является UILabels, поэтому все клиенты будут использовать файл UILabelsFile, поэтому загрузчик ResourceBundle не работает рекурсивно.
Другие советы
Вы можете написать собственный PropertyResolver, а затем заставить его выполнять логику, из которой нужно извлечь значения свойств.
Например, вы можете определить bean-компонент с именем messageSource
и загрузить его application.properties, а также ваши свойства CMS или все, что у вас есть.
Затем напишите пользовательский PropertyResolver
(есть пример того, как это сделать с помощью источника сообщений Spring . здесь ) и свяжите его со своим faces-config.xml
, используя что-то вроде этого:
<application>
<property-resolver>
com.package.MessageSourcePropertyResolver
</property-resolver>
</application>