Де розмістити і як читати файли ресурсів конфігурації в додатку на основі сервлетів?


222

У своєму веб-додатку я мушу надсилати електронний лист наборам наперед визначених користувачів finance@xyz.com, тому я хочу додати його до .propertiesфайлу та отримати доступ до нього, коли потрібно. Це правильна процедура, якщо так, то де я повинен розмістити цей файл? Я використовую Netbeans IDE, який має дві окремі папки для вихідних та JSP-файлів.


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

Відповіді:


464

Це твій вибір. В архіві веб-додатків Java (WAR) в основному є три способи:


1. Помістіть його в класі

Так що ви можете завантажити його за ClassLoader#getResourceAsStream()допомогою відносного шляху до класу:

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");
// ...

Однак видимість файлу властивостей залежить від відповідного завантажувача класів. Це видно лише тому ж завантажувачу класу, що і той, який завантажив клас. Отже, якщо клас завантажується, наприклад, загальним серверним завантажувачем сервера замість webapp classloader, а файл властивостей знаходиться всередині самого webapp, він невидимий. Завантажувач контекстного класу - це ваша найбезпечніша ставка, тому ви можете розмістити файл властивостей "скрізь" на classpath та / або ви маєте намір перемогти сервер із веб-сайту.


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, тоді покладіть її на класний шлях за межами проекту (за потреби додайте каталог до classpath).

Якщо ви віддаєте перевагу можливості редагування файлів властивостей програмно зсередини веб-програми за допомогою Properties#store()методу, поставте її поза веб-додатком. Як Properties#store()вимагає a Writer, ви не можете обійти шлях, використовуючи шлях до файлової системи диска. Цей шлях у свою чергу може бути переданий веб-додатку як аргумент VM або властивість системи. В якості запобіжних заходів ніколи не використовуйтеgetRealPath() . Усі зміни в папці розгортання втрачаються при повторному застосуванні з тієї простої причини, що зміни не відображаються в оригінальному файлі WAR.

Дивитися також:


2
"Я особисто вважаю за краще ставити його на classpath за межами проекту (додати новий шлях до classpath)" плутати, чи можна навести приклад?
Бланкмен

4
@Blankman Він, ймовірно, означає створити нову папку, помістити туди всі свої власні файли конфігурації та додати цю папку до classpath. Отже: 1) Створіть десь папку під назвою "appconfs" (можливо, навіть /etc/appconfs2). Додайте цю папку до класного шляху сервера / домену додатків. Другий крок - специфічний сервер додатків, я не думаю, що для цього є загальний приклад.
Tuukka Mustonen

Re: 2: Чому б і те, "WEB-INF/filename.properties"і "/WEB-INF/filename.properties"(зауважте, /на початку) працювали? Чи є якась причина віддавати перевагу одному перед іншим?
Mr_and_Mrs_D

Я був виправлений у цьому питанні за останній день. Я не в змозі завантажити свій файл властивостей. Я в змозі завантажити його з двох місць. Один - це системний каталог, а один - локальний диск. Він працює з localhost. Але я хочу розгорнути його на Amazon.
Арун Раджа

Я використовую IDE Netbeans і зберігаю файл властивостей у Веб-сторінках / ресурсах. Я намагаюся отримати доступ до нього як "./Web Pages / resources / config.properties". Я не маю доступу до нього. Будь ласка, допоможи мені.
Арун Раджа

9

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

Я навчився важко, що якщо ви "копіюєте" веб-проект у Eclipse, він очищає / відновлює з будь-яких папок-джерел. У моєму випадку я додав "пов'язаний джерело dir" з нашої бібліотеки Java POJO, він збирається в WEB-INF/classesпапку. Очищення / відновлення цього проекту (а не проекту веб-додатків) спричинило ту саму проблему.

Я думав над тим, щоб помістити мою конфс в папку src POJO, але ці конфс - це для інших сторонніх ліблів (наприклад, кварцових або URLRewrite), які знаходяться в WEB-INF/libпапці, так що це не мало сенсу. Я планую тестувати, щоб розмістити його в папці "src" веб-проектів, коли я обійдуся до неї, але ця папка наразі порожня, і в ній є конф-файли, здається, неелегантно.

Тому я голосую за покласти конфігураційні файли WEB-INF/commonConfFolder/filename.properties, поруч з папкою класів, яка є варіантом Балус 2.


1
якщо ви помістите ваш конфігураційний файл у підпапку WEB_INF, то як до нього дійти? Мені не пощастило сказати "configFiles / prop.properties"
JesseBoyd

Ок, це працює, розміщуючи файл властивостей у розділі "Ресурси Java / src /", він не працює в одному з моїх пакетів і повинен бути в корені src. ваше попередження про нульову папку класів викликає занепокоєння.
JesseBoyd

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 ви можете оголосити свої властивості таким

Для Ex:

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

Він просто повинен знаходитись у classpath (він також переконайтесь, що він закінчується під / WEB-INF / класами у .war як частина збірки).


привіт спасибі за ідею, але він мені каже, що не вдається знайти вказаний файл, так це проблема шляху, як дати шлях
sansknwoledge

3

Ви можете зі своєю вихідною папкою, тому щоразу, коли ви створюєте, ці файли автоматично копіюються в каталог класів.

Замість файлу властивостей використовуйте XML-файл.

Якщо даних занадто мало, ви навіть можете використовувати web.xml для доступу до властивостей.

Зауважте, що будь-який із цих підходів потребує перезавантаження сервера додатків, щоб зміни відображалися.


я помістив у папку веб-сторінок, але не
маючи

1
якщо ваш файл потрапляє в папку WEB-INF / класів, він автоматично встановлюється у класний шлях
Kalpak

2

Припустимо, ваш код шукає файл скажімо app.properties. Скопіюйте цей файл у будь-який dir та додайте цей dir до classpath, створивши setenv.sh у bin dir 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 / класів /

Гарне прочитання: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.