Где разместить и как прочитать файлы ресурсов конфигурации в приложении на основе сервлетов?


222

В моем веб-приложении мне нужно отправить электронное письмо заранее определенным пользователям, например finance@xyz.com, поэтому я хочу добавить его в .propertiesфайл и получить к нему доступ при необходимости. Это правильная процедура, если да, то где мне разместить этот файл? Я использую Netbeans IDE, в которой есть две отдельные папки для файлов исходного кода и JSP.


JNDI, возможно, может быть решением?
Василий Бурк

Ответы:


464

Это твой выбор. В архиве веб-приложений Java (WAR) есть три основных способа:


1. Поместите это в classpath

Так что вы можете загрузить его ClassLoader#getResourceAsStream()с помощью пути к классам:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);

Здесь foo.propertiesпредполагается поместить в один из корней, которые охватываются стандартным путем к классу веб-приложения, например, веб-приложение /WEB-INF/libи /WEB-INF/classesсервер /lib, или JDK / JRE /lib. Если файл свойств зависит от веб-приложения, лучше всего поместить его в /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");
// ...

Однако видимость файла свойств зависит от загрузчика классов. Он виден только тому загрузчику классов, который загрузил класс. Таким образом, если класс загружается, например, общим загрузчиком классов сервера вместо загрузчика классов веб-приложения, и файл свойств находится внутри самого веб-приложения, то он невидим. Загрузчик классов контекста - ваша самая безопасная ставка, поэтому вы можете поместить файл свойств «везде» в путь к классам, и / или вы намерены иметь возможность переопределить файл, предоставленный сервером, из веб-приложения.


2. Поместите это в веб-контент

Так что вы можете загрузить его ServletContext#getResourceAsStream()с помощью относительного к веб-пути пути:

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, вы не можете использовать путь к файловой системе диска. Этот путь, в свою очередь, может быть передан веб-приложению в качестве аргумента виртуальной машины или системного свойства. В качестве меры предосторожности никогда не используйтеgetRealPath() . Все изменения в папке развертывания будут потеряны при повторном развертывании по той простой причине, что изменения не отражаются обратно в исходном файле WAR.

Смотрите также:


2
«Я лично предпочитаю помещать его в путь к классам вне проекта (добавить новый путь к пути к классам)», вы не можете привести пример?
Бланкмен

4
@Blankman Он, вероятно, подразумевает создание новой папки, размещение всех ваших пользовательских файлов конфигурации и добавление этой папки в путь к классам. Итак: 1) Создайте папку с именем appconfs (может быть даже /etc/appconfs2). Добавьте эту папку в classpath сервера / домена приложения. Второй шаг зависит от сервера приложений, я не думаю, что есть общий пример для этого.
Туукка Мустонен

Re: 2: Почему оба "WEB-INF/filename.properties"и "/WEB-INF/filename.properties"(обратите внимание /на в начале) работать? Есть ли причина предпочитать одно другому?
Mr_and_Mrs_D

Я был исправлен в этой проблеме в течение прошлого дня. Я не могу загрузить свой файл свойств. Я могу загрузить его из двух мест. Один из них - системный каталог, а второй - локальный диск. Работает с localhost. Но я хочу развернуть его на Амазонке.
Арун Раджа

Я использую NetBeans IDE и храню файл свойств в Web Pages / resources. Я пытаюсь получить доступ к нему как "./Web Pages / resources / config.properties". Я не могу получить к нему доступ. Пожалуйста, помогите мне.
Арун Раджа

9

Слово предупреждения: если вы поместите файлы конфигурации в вашу WEB-INF/classesпапку, и ваша IDE, скажем, Eclipse, выполнит очистку / перестройку, она уничтожит ваши файлы conf, если они не были в исходном каталоге Java. Отличный ответ BalusC намекает на это в варианте 1, но я хотел добавить акцент.

Я усвоил трудный путь, что если вы «копируете» веб-проект в Eclipse, он выполняет очистку / перестройку из любых исходных папок. В моем случае я добавил «dir связанный источник» из нашей библиотеки Java POJO, он будет скомпилирован в WEB-INF/classesпапку. Выполнение очистки / перестройки в этом проекте (не в проекте веб-приложения) вызвало ту же проблему.

Я думал о том, чтобы поместить свои файлы в папку POJO src, но все эти файлы предназначены для сторонних библиотек (таких как Quartz или URLRewrite), которые находятся в WEB-INF/libпапке, так что это не имело смысла. Я планирую проверить, поместив его в папку «src» веб-проектов, когда доберусь до него, но в данный момент эта папка пуста, и файлы conf в ней кажутся не элегантными.

Поэтому я голосую за положить конфигурационные файлы WEB-INF/commonConfFolder/filename.properties, рядом с папкой классов, которая является вариантом Балус 2.


1
если вы поместите свой конфигурационный файл в подпапку WEB_INF, то как вы его достигнете? Мне не повезло, скажем, 'configFiles / prop.properties'
JesseBoyd

хорошо, это работает, помещая файл свойств в 'Java Resources / src /', он не работает внутри одного из моих пакетов и должен находиться в корне src. Ваше предупреждение о том, что папка классов взломана, является действительной проблемой.
ДжессиБойд

6

Пример: в файле web.xml тег

<context-param>
        <param-name>chatpropertyfile</param-name>
        <!--  Name of the chat properties file. It contains the name and description                   of rooms.-->     
        <param-value>chat.properties</param-value>
    </context-param>

И chat.properties вы можете объявить свои свойства, как это

Например:

Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.

5

Он просто должен быть в пути к классам (он также должен быть в каталоге / WEB-INF / classes в .war как часть сборки).


Привет, спасибо за идею, но он говорит мне, что не может найти указанный файл, да это проблема пути, как дать путь
sansknwoledge

3

Вы можете использовать исходную папку, чтобы при создании эти файлы автоматически копировались в каталог классов.

Вместо использования файла свойств используйте файл XML.

Если данные слишком малы, вы даже можете использовать web.xml для доступа к свойствам.

Обратите внимание, что любой из этих подходов потребует перезапуска сервера приложений, чтобы изменения были отражены.


я поместил в папку веб-страниц, но не смог получить к нему доступ к файлу не найден ошибка приходит, как установить путь
sansknwoledge

1
если ваш файл попадает в папку WEB-INF / classes, он автоматически устанавливается в путь к классам
Kalpak

2

Предположим, ваш код ищет файл, скажем, app.properties. Скопируйте этот файл в любой каталог и добавьте этот каталог в classpath, создав файл setenv.sh в каталоге bin в tomcat.

В вашем setenv.sh tomcat (если этот файл не существует, создайте его, tomcat загрузит этот файл setenv.sh). #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

Вы не должны иметь свои файлы свойств в ./webapps//WEB-INF/classes/app.properties

Загрузчик классов Tomcat переопределит тот из WEB-INF / classes /

Хорошее чтение: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.