JavaRush /Java блог /Random UA /Без пафосу. Поговоримо про Java EE, сервлети та їх контей...
eGarmin
41 рівень

Без пафосу. Поговоримо про Java EE, сервлети та їх контейнери

Стаття з групи Random UA
У цьому топіку я б хотів відверто поговорити про моє розуміння сервлетів, що є контейнери сервлетів, що є більшість, якщо не всі, веб-фронт-енд-фреймворки, а також торкнутися теми, як співвідносяться між собою контейнери сервлетів і сервера додатків, та контейнери сервлетів та веб-сервера. Без пафосу.  Поговоримо про Java EE, сервлети та їх контейнери - 1Перед початком розмови хочу відзначити, що я дійсно розраховую, що вийде дискусія, т.к. тут мені не хочеться наводити ні шматочка коду, а хочеться торкнутися лише суті, яку можна викласти на словах. Спробую викласти всі ті моменти, які були мені не зрозумілі, коли я тільки починав. Коли я ставив запитання на різних форумах на тему, чим відрізняється контейнер сервлетів Tomcat від будь-якого сервера додатків, скажімо WebSphere або Geronimo, то відповідати вирішувалися лише козли, які не можуть сказати нічого, окрім «дивися вікіпедію» або «це складно сказати, сервер додатків – це для корпоративних програм складна інфраструктура, яка…» бла-бла-бла. Терпіти таких не можу і вважаю, що більшість із вас також. Виправлятимемо історичну несправедливість. Поїхали…

Сервлети

Щоб хтось там не говорив, сервлет – це веб-сторінка, написана на Java. Деякі скажуть, що я не маю рації і сервлет – це веб-додаток і що є різниця в цих поняттях, але це не так. Наразі вже різниці немає, і сайти, написані на PHP, теж можна сміливо називати веб-додатками. Тепер це цілком закономірно, т.к. php підтримує ООП повною мірою, а такі CMS як Joomla активно користуються цим. Що таке сервлет лише на рівні коду? Це клас, у якому є низка методів, які сплять і бачать, щоб хтось звернувся до них через GET або POST запити HTTP. Тобто. набрали ми у браузері деякий запит GET, відповідний метод класу сервлета його приймає і далі формує у відповідь нього як html-сторінки. У класичному розумінні сервлета, як він був задуманий ще Sun, ця сторінка так і відправлялася клієнтові рядок за рядком, починаючи з рядка <!DOCTYPE htm>> і закінчуючи рядком </ html>. Таким чином, в Java є базовий сервлет клас на ім'яServlet. Крім того, є купа інших класів, які успадковуються від цього базового класу і тим самим розширюють його функціональність. Ось що таке сервлет – більше нічого. Просто Java аналог PHP коду, який також виконується на сервері, а клієнту надсилається тільки відповідь на запит веб-браузера у вигляді веб-сторінки. Всі.

Веб-фронт-енд-фреймворки

Підзаголовок складний і зазвичай все ж таки пишуть просто фронт-енд-фреймворк або навіть веб-морда , але я вирішив тут підкреслити, що коли йдеться про фронт-енд-фреймворки, то говорять про GUI для роботи з Java через веб-браузер. Тобто. тут знову йдеться про веб-сайти Java, тобто. про сервлети. Що ж є майже будь-який фронт-енд фреймфорк, наприклад, Apache Struts. Це просто набір класів, які розширюють базовий клас Servlet. Більше нічого. Тобто. це просто інший спосіб створити той же звичайний сервлет. Просто розробники цього фреймфорка (або інакше кажучи, розробники цієї технології) вважали, що їх доповнення базовогоServlet-Класу деякими методами буде зручніше для програміста, ніж той мізерний функціонал, що є у класичного сервлета від Sun / Oracle.

JSP-сторінки

Практично відразу ж на думку розробників концепції Java-сервлетів спала ще одна ідея. Якщо ми пишемо сервлет, завдання якого – це відправка клієнту html-сторінки, то може правильніше відразу написати цю html-сторінку, а вже якщо знадобиться якась логіка на Java, то просто вставляти її безпосередньо в html. Якщо зрозуміліше не стало, може допомогти фраза: jsp-сторінка – це аналог php-сторінки. Важко? Тоді ще поясню. Що ми робимо під час написання сторінки на php? У нас йде статичний html, а коли потрібно вставити будь-яку логіку на php типу циклів та умов, то ми вставляємо її в тіло тега <?php … ?>. З jsp все те саме, тільки логіка пишеться на чистій Java, код якої вставляється в тіло тега<% … %>. Ще раз повернемось до поняття сервлету. По суті jsp-сторінка – це і є сервлет, але записаний трохи інакше. У звичайному сервлет ми пишемо метод, який виконує деяку логіку і за її результатами формує для клієнта html-сторінку. Просто через якийсь час розробники сервлетів задумалися, а що, якщо в методі не буде практично ніякої логіки, а йтиме майже одне лише формування html-сторінки, то чи не простіше буде писати відразу html-сторінку, в яку робити мінімальні вставки Java коду. Та й останнє з приводу jsp-сторінок. При першому зверненні до такої сторінки вона компілюється в сервлет і виконується. Подальші запити до цієї jsp-сторінці будуть швидше, т.к. вона вже буде скомпільована і її потрібно буде лише виконати.

Контейнер сервлетів

Ось ми написали клас сервлета або jsp-сторінку. Що далі? Як їх запхати в веб-сервер, скажімо apache, щоб той зміг їх відправити користувача веб-браузеру? Веб-сервер може надсилати лише html, а якщо на нашій сторінці є, скажімо, php-код, то веб-сервер спочатку пропускає сторінку через інтерпретатор, що перекладає php в html, і лише потім результат відправляється клієнту. З сервлетами відбувається приблизно те саме – перед відправкою їх потрібно виконати, щоб сформувалася html сторінка, а контейнер сервлетів якраз та сама штука, яка відповідає за виконання сервлетів та коду jsp-сторінок. Тобто. контейнер сервлетів для java – це аналог модуля php-інтерпретатора у веб-сервері. Таким чином, коли користувач у рядку веб-браузера вводить адресау, цей запит надсилається веб-серверу, веб-сервер розуміє, що запитує сервлет, та передає запит контейнеру сервлетів. Після цього контейнер сервлет виконує сервлет, отриману html-сторінку відправляє веб-серверу, а той, у свою чергу, повертає її клієнту. Чи може контейнер сервлетів працювати сам собою, тобто. без веб-сервера? Такий як Tomcat – напевно може. І якщо ми хочемо створити сайт, у якого не буде жодних інших html-сторінок, окрім як заснованих на сервлетах, то контейнера сервлетів нам цілком достатньо. А ось якщо ми захочемо комбінувати сайт із сервлетів та скажемо php-сторінок, то доведеться ставити веб-сервер. Причому не всі веб-сервера мають контейнер сервлетів у своєму складі за замовчуванням, зате майже всі дозволяють поставити його як плагін. Тому якщо ми захочемо запустити наш сайт на якомусь хостингу в інтернеті, де, швидше за все, працює apache,

Java EE

Є так званий JavaSE (Java Standard Edition). До цього поняття відносяться всі класи java, для використання яких нам достатньо їх просто імпортувати (наприклад, java.util.Date) або навіть цього робити не треба (наприклад, Stringтому що він розташовується в пакеті java.lang). А є Java EE (Java Enterprise Edition). Ці класи теж належать Sun/Oracle, але різниця лише в тому, що їх складніше використовувати в проекті. Простий рядки import…буде замало, т.к. проект не компілюватиметься. Для того, щоб виправити ситуацію, потрібно буде знайти файл бібліотеки javaee.jar та підключити його до проекту. Зробити це можна через характеристики проекту серед розробки. Часто кажуть, що цей процес підключення називається – прописати jar-нік у build pathабо classpath проекту.

Сервер додатків

Тепер уявіть, що ми скомпілювали наш проект-сервлет, який використовує Java EE. Все чудово, але нам тепер потрібно розмістити наші скомпільовані класи у контейнері сервлетів. Припустимо, зробабо. Чи працюватиме наша програма. Відповідь – ні. При зверненні до сервлета полетять виняткові ситуації, що якихось класів не знайдено. Чому? Тому що компілятор ми «обдурабо», підсунувши javaee.jar в classpath, тобто. компілятор побачив, що класи з Java EE на місці і заспокоївся, а от контейнер сервлетів цих класів не бачить, зате бачить посилання на них із нашого сервлету. Чи можна вирішити цю ситуацію в рамках контейнера сервлетів. Звичайно так, потрібно просто в контейнері сервлетів до папки з нашим сервлетом додати файл бібліотеки javaee.jar. А тепер уявіть, що таких проектів буде багато, і всі вони запущені в одному контейнері сервлетів Tomcat. Це означає, що в папку кожного сервлета доведеться копіювати цей файл jar. Це незручно та неправильно. Ситуація вирішилася шляхом введення поняття сервера програми, в якому цей файл уже давно лежить в єдиному екземплярі, і всі сервлети можуть до нього звертатися, а не мати свою копію. На мій погляд, дуже зручно та логічно. Звичайно, весь сир бор не через одне jar-файлу (його я навів для прикладу) – таких файлів багато. Але це не все, що дають нам сервер додатків. Сервера програм можуть самі тримати з'єднання з багатьма ресурсами, наприклад, з базою даних. При цьому наш сервлет може сам таке з'єднання не відкривати, а просто брати його із сервера додатків. У контейнері сервлетів – це неможливо, т.к. контейнер – це, до певної міри, урізаний сервер додатків. У контейнері сервлет повинен завжди сам створювати коннекшен до бази. Якось так… war-архів Що таке war-архів? WAR – це веб-архів (веб-архів). Насправді це просто zip-файл, як і будь-який jar-нік. По суті, це лише спосіб, щоб наш веб-сайт, що складається з безлічі веб-сторінок, jsp-сторінок і класів сервлетів запихати в один файл формату zip. web.xml web.xml – це так званий дескриптор розгортання. Це файл, в якому тупо описано, який запит рядка веб-браузера на обробку якомусь класу-сервлету відправляти, щоб контейнер сервлетів не заплутався, який сервлет за що відповідає. В цілому, в Java дуже модно описувати налаштування у всяких xml-файлух, але останнім часом намітилася тенденція уникнення цієї традиції. Як, спитаєте ви? А через інструкції. Класи-анотації самі нічого не роблять, вони якраз і створені тільки для того, щоб будь-які налаштування (мета-дані) описувати не в окремому xml-файлі, а прямо за кодом. Дуже зручно. Однак зараз спостерігається певна проміжна стадія, коли частина налаштувань задана інструкціями, а частина через xml, і це може заплутати, т.к. дивишся xml і бачиш одну настройку, а по анотаціях стоїть інша. Яка з них має найвищий пріоритет? Хто знає…

Висновок

Написавши це, я задумався, що такий побіжний огляд нікому не допоможе, т.к. не містить жодної конкретики та жодних прикладів, але з іншого боку не стирати ж написане, тож нехай буде.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ