Я создаю веб-приложение (WAR) и развертываю его на Tomcat. В веб-приложение есть страница с формой, где администратор может ввести некоторые данные конфигурации. Я хочу хранить эти данные не в СУБД, а только в XML-файле файловой системы. Куда его поставить?
Я хотел бы поместить файл где-нибудь в дереве каталогов, где развернуто само приложение. Должен ли мой файл конфигурации находиться в каталоге WEB-INF? Или еще куда-нибудь положить?
И какой код Java использовать в сервлете, чтобы найти абсолютный путь к каталогу? Или к нему можно получить доступ по относительному пути?




Я бы не стал хранить его в папке приложения, потому что это переопределит конфигурацию с новым развертыванием приложения.
Я предлагаю вам взглянуть на Preferences API или написать что-нибудь в папке пользователей (пользователь, который запускает Tomcat).
Ответ на этот вопрос зависит от того, как вы собираетесь читать и записывать этот файл конфигурации.
Например, среда Spring дает вам возможность использовать использовать файлы конфигурации XML (или файлы свойств Java); они могут храниться в вашем пути к классам (например, в каталоге WEB-INF), в любом другом месте файловой системы или даже в памяти. Если бы вы использовали Spring для этого, то проще всего сохранить файл конфигурации в вашем каталоге WEB-INF, а затем использовать класс Spring ClassPathXmlApplicationContext для доступа к вашему файлу конфигурации.
Но опять же, все зависит от того, как вы планируете получить доступ к этому файлу.
Если это ваша индивидуальная конфигурация, WEB-INF - хорошее место для нее. Но некоторые библиотеки могут требовать, чтобы конфигурации располагались в WEB-INF / classes.
Что мы делаем, так это помещаем его в отдельный каталог на сервере (вы можете использовать что-то вроде / config, / opt / config, / root / config, / home / username / config или что угодно). Когда наши сервлеты запускаются, они читают XML-файл, извлекают из него кое-что (самое главное - информацию о соединении с БД), и все.
Я спросил, почему мы однажды это сделали.
Было бы неплохо хранить все в БД, но, очевидно, вы не можете хранить информацию о подключении к БД в БД.
Вы можете жестко запрограммировать что-то в коде, но это некрасиво по многим причинам. Если информация когда-либо должна измениться, вам придется перестроить код и выполнить повторное развертывание. Если кто-то получит копию вашего кода или вашего файла WAR, он получит эту информацию.
Помещение чего-либо в файл WAR кажется приятным, но если вы хотите сильно что-то изменить, это может быть плохой идеей. Проблема в том, что если вам нужно изменить информацию, то при следующем повторном развертывании он перезапишет файл, поэтому все, что вы не забыли изменить в версии, встроенной в WAR, будет забыто.
Файл в специальном месте файловой системы у нас работает очень хорошо. У него нет больших минусов. Вы знаете, где он находится, он хранится отдельно, что упрощает развертывание на нескольких машинах, если всем им нужны разные значения конфигурации (поскольку он не является частью WAR).
Единственное другое решение, которое я могу придумать, которое будет работать хорошо, - это сохранить все в БД, кроме информации для входа в БД. Это может происходить из свойств системы Java, которые извлекаются через JVM. Это API настроек, упомянутый выше Хансом Доггеном. Я не думаю, что это было когда-то, когда наше приложение только разрабатывалось, если бы оно не использовалось.
Что касается пути доступа к файлу конфигурации, это просто файл в файловой системе. Вам не нужно беспокоиться о веб-пути. Поэтому, когда ваш сервлет запускается, он просто открывает файл по адресу «/config/myapp/config.xml» (или что-то еще), и он найдет то, что нужно. Просто жестко запрограммировать путь для этого кажется мне довольно безобидным.
Это работает и для нас, но может быть неприятно, если вы время от времени развертываете в Windows, где неестественно добавлять / opt и тому подобное.
Вместо того, чтобы ссылаться на полный путь к файлу, вы можете поместить каталог «config» в путь к классам для сервера и просто использовать ClassLoader.getResource ().
Мы указываем системное свойство при запуске tomcat. Ваше приложение получает наш каталог конфигурации из этого системного свойства, поэтому мы можем использовать разные каталоги конфигурации от сервера к серверу.
Спасибо за ваши предложения. Они мне очень пригодились.
@Peter: Моя установка для разработчиков была в Windows. Я просто создал каталог на своем ящике вне C, чтобы, когда приложение запросило «/ config», оно получило правильный каталог. Это сработало довольно хорошо.
@John: На самом деле это неплохая идея, это была просто установка, когда я туда приехал.
В приложении, над которым я сейчас работаю, мы храним файл конфигурации вне приложения в папке, расположенной в каталоге USER_HOME. И при запуске приложение получает файл из местоположения String absoluteConfigPath = System.getProperty ("user.home") + File.separator + ".myapp" + File.separator + "config.xml";
небольшое замечание: согласно руководству по иерархии файловой системы tldp.org/LDP/Linux-Filesystem-Hierarchy/html/opt.html, все файлы должны находиться в / opt / 'package' / config, где 'package' - это имя вашей программы.
@MBCook Спасибо за ваш комментарий. Это развеяло мои сомнения.
Как это будет работать, если у вас есть несколько сред (например, тестовых и промежуточных), работающих в одном и том же коте? Поскольку вы не можете указать системное свойство для каждой среды, когда у вас есть только один кот.
WEB-INF - хорошее место для размещения вашего файла конфигурации. Вот код для получения абсолютного пути к каталогу из сервлета.
public void init(ServletConfig servletConfig) throws ServletException{
super.init(servletConfig);
String path = servletConfig.getServletContext().getRealPath("/WEB-INF")
Это несовместимый подход - спецификация сервлета не гарантирует, что getRealPath () вернет действительный (ненулевой) путь или даже что война вообще распакована (IMHO, Weblogic не будет извлекать файлы из .war в диск).
Это не сработает, если у вас есть среда разработки, тестирования, предварительной подготовки и разработки, поскольку вам потребуется отдельный .war для каждой среды. Вы должны иметь возможность развернуть конфигурацию один раз, а затем распространить ту же войну по средам ...
Помещение его в WEB-INF скроет XML-файл от пользователей, которые попытаются получить к нему доступ напрямую через URL-адрес, поэтому да, я бы сказал, поместите его в WEB-INF.
Обратите внимание, что для механизмов сервлетов нет механизма по умолчанию - вам нужно будет сделать предположения, специфичные для поставщика.