Есть ли способ получить доступ к web.xml свойствам из Java Bean?
Вопрос
Есть ли в API сервлета какой-либо способ получить доступ к свойствам, указанным в web.xml (таким как параметры инициализации), изнутри класса Bean или Factory, который вообще не связан с веб-контейнером?
Например, я пишу класс Factory, и я хотел бы включить некоторую логику в Factory для проверки иерархии файлов и расположений конфигурации, чтобы увидеть, какие из них доступны, если таковые имеются, чтобы определить, какой класс реализации создавать - например,
- файл свойств в пути к классу,
- web.xml параметр,
- системное свойство, или
- некоторая логика по умолчанию, если больше ничего не доступно.
Я хотел бы иметь возможность сделать это, не вводя никаких ссылок на ServletConfig
или что-нибудь похожее на мою Фабрику - код должен нормально работать вне контейнера сервлета.
Это может показаться немного необычным, но я бы хотел, чтобы этот компонент, над которым я работаю, мог быть упакован с одним из наших веб-приложений, а также был достаточно универсальным, чтобы его можно было упаковывать с некоторыми из наших инструментов командной строки, не требуя нового файла свойств только для моего компонента - так что я надеялся использовать другие файлы конфигурации, такие как web.xml .
Если я правильно помню, в .NET есть что-то вроде Request.GetCurrentRequest()
чтобы получить ссылку на выполняемый в данный момент Request
- но поскольку это Java-приложение, я ищу что-то похожее, что можно было бы использовать для получения доступа к ServletConfig
.
Решение
Один из способов, которым вы могли бы это сделать, это:
public class FactoryInitialisingServletContextListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent event) {
}
public void contextInitialized(ServletContextEvent event) {
Properties properties = new Properties();
ServletContext servletContext = event.getServletContext();
Enumeration<?> keys = servletContext.getInitParameterNames();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
String value = servletContext.getInitParameter(key);
properties.setProperty(key, value);
}
Factory.setServletContextProperties(properties);
}
}
public class Factory {
static Properties _servletContextProperties = new Properties();
public static void setServletContextProperties(Properties servletContextProperties) {
_servletContextProperties = servletContextProperties;
}
}
И затем имейте в своем распоряжении следующее web.xml
<listener>
<listener-class>com.acme.FactoryInitialisingServletContextListener<listener-class>
</listener>
Если ваше приложение запущено в веб-контейнере, то прослушиватель будет вызван контейнером после создания контекста.В этом случае _servletContextProperties будут заменены любыми контекстными параметрами, указанными в web.xml.
Если ваше приложение запущено вне веб-контейнера, то _servletContextProperties будет пустым.
Другие советы
Рассматривали ли вы возможность использования Spring Framework для этого?Таким образом, ваши компоненты не будут подвергаться дополнительной обработке, и spring выполнит настройку конфигурации за вас.
Я думаю, что вам нужно будет добавить связанный класс начальной загрузки, который принимает ссылку на ServletConfig (или ServletContext) и переписывает эти значения в класс Factory.По крайней мере, таким образом вы можете упаковать его отдельно.
@инструментарий :Превосходно, с величайшим смирением - это то, что я пытался сделать в течение некоторого времени