Ответ 1
Это ваш выбор. В основном архиве веб-приложений Java (WAR) есть три способа:
1. Поместите его в classpath
Чтобы вы могли загрузить его ClassLoader#getResourceAsStream()
с относительным путем classpath:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
Здесь foo.properties
предполагается разместить в одном из корней, которые покрываются путём по умолчанию для webapp, например. webapp /WEB-INF/lib
и /WEB-INF/classes
, сервер /lib
или JDK/JRE /lib
. Если файл свойств специфичен для webapp, лучше всего поместить его в /WEB-INF/classes
. Если вы разрабатываете стандартный проект WAR в среде IDE, поместите его в папку src
(исходная папка проекта). Если вы используете проект Maven, поместите его в папку /main/resources
.
Вы также можете поместить его куда-то за пределы пути по умолчанию и добавить его путь к пути к классам на сервере приложений. Например, в Tomcat вы можете настроить его как shared.loader
свойство Tomcat/conf/catalina.properties
.
Если вы разместили foo.properties
его в структуре пакета Java, например com.example
, вам необходимо загрузить его ниже
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
Обратите внимание, что этот путь загрузчика класса контекста не должен начинаться с /
. Только когда вы используете "относительный" загрузчик классов, например SomeClass.class.getClassLoader()
, вам действительно нужно запустить его с помощью /
.
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
Однако видимость файла свойств зависит от того, какой класс загрузчика класса находится под вопросом. Он доступен только для того же загрузчика классов, что и тот, который загружал класс. Таким образом, если класс загружается, например, server common classloader вместо загрузчика классов webapp, а файл свойств находится внутри самого webapp, а затем он невидим. Загрузчик класса контекста - это ваша самая безопасная ставка, поэтому вы можете поместить файл свойств "всюду" в путь к классам и/или вы намереваетесь переопределить предоставленный сервером один из веб-сервера.
2. Поместите его в webcontent
Чтобы вы могли загрузить его ServletContext#getResourceAsStream()
с относительным путем webcontent:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
Обратите внимание, что я продемонстрировал размещение файла в папке /WEB-INF
, иначе он был бы общедоступным для любого веб-браузера. Также обратите внимание, что ServletContext
находится в любом классе HttpServlet
, доступном только для унаследованного GenericServlet#getServletContext()
и Filter
FilterConfig#getServletContext()
. Если вы не находитесь в классе сервлета, он обычно просто вводится через @Inject
.
3. Поместите его в локальную файловую систему диска
Чтобы вы могли загрузить обычный java.io
путь с полным пути к файловой системе локального диска:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
Обратите внимание на важность использования абсолютного пути. Относительные пути локальной файловой системы на диске - это абсолютное отсутствие в веб-приложении Java EE. См. Также первую ссылку "См. Также" ниже.
Что выбрать?
Просто взвешивайте преимущества/недостатки в своем собственном мнении о ремонтопригодности.
Если файлы свойств "статические" и никогда не должны меняться во время выполнения, вы можете сохранить их в WAR.
Если вы предпочитаете редактировать файлы свойств вне веб-приложения без необходимости пересортировки и повторного развертывания WAR каждый раз, тогда поместите его в путь класса вне проекта (при необходимости добавьте каталог в путь к классам).
Если вы предпочитаете редактировать файлы свойств программным способом из веб-приложения с помощью метода Properties#store()
, выведите его за пределы веб-приложения. Поскольку для Properties#store()
требуется Writer
, вы не можете использовать путь к файловой системе диска. Этот путь, в свою очередь, может быть передан в веб-приложение как аргумент VM или системное свойство. В качестве меры предосторожности никогда используйте getRealPath()
. Все изменения в папке развертывания будут потеряны при повторном развертывании по той простой причине, что изменения не будут отражены в исходном файле WAR.