1. Метод init()
І ще пара корисних дрібниць. Звісно, я про ініціалізацію сервлета. Як ти вже знаєш, після того, як веб-сервер створив об'єкт сервлета та помістив його в контейнер, він викликає у сервлета метод init(). Ти можеш перевизначити цей метод та ініціалізувати у ньому все, що тобі потрібно.
А чому б не використати конструктор?
Тому що процес створення сервлету відбувається приблизно так:
- Створюємо об'єкт, успадкований від HttpServlet
- Створюємо об'єкт ServletContext, додаємо його змінну сервлета
- Створюємо об'єкт ServletConfig, додаємо його змінну сервлета
- …
- Веб-сервер приєднує сервлет до контейнера
- Викликаємо метод init()
У конструкторі твого сервлета ще багато його внутрішніх змінних не ініціалізовано. Контейнер нічого не знає про твій сервлет, твій сервлет нічого не знає про його контекст. Думаю, тут і так зрозуміло.
Давай напишемо сервлет, який при ініціалізації знаходить properties-файл з налаштуваннями:
public class PropertiesServlet extends HttpServlet {
public init() {
try (InputStream input = new FileInputStream("c:/path/to/config.properties")) {
Properties prop = new Properties();
prop.load(input);
String databaseURL = prop.getProperty("db.url");
String databaseUser = prop.getProperty("db.user ");
String databasePassword = prop.getProperty("db.password");
}
}
}
Тут ми створюємо об'єктProperties і завантажуємо в нього дані із файлу config.properties. Ну і надалі можна діставати з об'єкту Properties різні параметри, такі як дані для доступу до бази даних, наприклад.
2. Як правильно завантажити properties-файл
До речі, а що робити, якщо твій сервлет виконується не на комп'ютері?
Скажімо, написали його тут, а він виконується на сервері десь в іншій частині світу. Або на кількох серверах. Як правильно завантажити properties-файл у цьому випадку?
Гарне питання. Зазвичай у процесі роботи сервлет знає лише відносний шлях своїх properties-файлів, але не знає їхнього абсолютного шляху, оскільки war-файли з сервлетами можуть зберігатися будь-де.
Отже, нам потрібно дізнатися шлях, де зберігається наш сервлет (сервлет вже проініціалізовано) і додати до нього відносний шлях :)
Виглядає це приблизно так:
String path = absoluteServletPath + "относительный путь";
І, як завжди, таке елементарне завдання часто має своє невелике “але”. Твій сервлет та його properties-файл зберігаються всередині архіву :) Не обов'язково, звичайно, але й таке буває. properties-файл часто зберігається всередині jar-або war-файлів.
Тобто фізичного шляху на диску твій файл може й не мати. Але оскільки контейнеру вдалося завантажити твій сервлет, він, швидше за все, зможе завантажити і твій properties-файл.
Для цього тобі потрібно отримати об'єкт завантажувача класу (ClassLoader) та попросити його завантажити твій файл. Ось як це виглядатиме:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream("/config.properties");
Properties prop = new Properties();
prop.load(stream);
3. Метод getConfig()
До речі, не всі параметри можна передавати до сервлета у properties-файлах. Наприклад, твій сервлет взаємодіє з іншими сервлетами в розподіленому вебзастосунку.
Тоді потрібно зробити так, щоб контейнер передав твоєму сервлету всю необхідну інформацію, коли він буде викликати його метод init(). Ба більше, він саме так і робить.
У твого сервлета (адже ти пам'ятаєш, що він успадкований від класу HttpServlet) є метод getServletConfig(), який повертає об'єкт ServletConfig, що створено та ініціалізовано контейнером. Цей об'єкт має такі методи:
getInitParameterNames() | Повертає список імен параметрів сервлету |
getInitParameter(String name) | Повертає параметр сервлета за його ім'ям |
getServletName() | Повертає власне ім'я сервлета |
getServletContext() | Повертає об'єкт ServletContext |
Давай напишемо сервлет, який повертає список своїх параметрів з ServletConfig. Класти їх туди будемо через файл web.xml:
<web-app>
<servlet>
<servlet-name>Print-Servlet</servlet-name>
<servlet-class>PrintServlet</servlet-class>
<init-param>
<param-name>jdbc-driver</param-name>
<param-value>sun.jdbc.odbc.JdbcOdbcDriver</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Print-Servlet</servlet-name>
<url-pattern>/print</url-pattern>
</servlet-mapping>
</web-app>
Отримати свої параметри сервлет може за допомогою коду:
public class PrintServlet extends HttpServlet {
public void init() {
ServletConfig config = this.getServletConfig();
Enumeration<String> initParameterNames = config.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
String key = initParameterNames.nextElement();
System.out.println("%s: %s\n", key, config.getInitParameter(key));
}
}
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ