Servlets
- Что такое «сервлет»?
- Что добавилось в спецификации Servlet 2.5, 3.0, 3.1, 4.0?
- В чем заключаются преимущества технологии сервлетов над CGI (Common Gateway Interface)?
- Что такое «контейнер сервлетов»?
- Зачем нужны сервера приложений, если есть контейнеры сервлетов?
- Как контейнер сервлетов управляет жизненным циклом сервлета, когда и какие методы вызываются?
- Что такое «дескриптор развертывания»?
- Какие действия необходимо проделать при создании сервлетов?
- Какие наиболее распространенные задачи выполняются в контейнере сервлетов?
- Что вы знаете о сервлетных фильтрах?
- Когда стоит использовать фильтры сервлетов, а когда слушателей?
- Какие основные особенности появились в спецификации Servlet 3?
- Какие способы аутентификации доступны сервлету?
- Что такое Java Server Pages (JSP)?
- Зачем нужен JSP?
- Взаимодействие JSP - сервлет - JSP
- Опишите общие практические принципы работы с JSP 3_?](#какие-основные-особенности-появились-в-спецификации-servlet-3)
- Какие способы аутентификации доступны сервлету?
- Что такое Java Server Pages (JSP)?
- Зачем нужен JSP?
- Взаимодействие JSP - сервлет - JSP
- Опишите общие практические принципы работы с JSP 3_?](#какие-основные-особенности-появились-в-спецификации-servlet-3)
- Какие способы аутентификации доступны сервлету?
- Что такое Java Server Pages (JSP)?
- Зачем нужен JSP?
- Взаимодействие JSP - сервлет - JSP
- Опишите общие практические принципы работы с JSP
Что такое «сервлет»?
Сервлет является интерфейсом, реализация которого расширяет функциональные возможности сервера. Сервлет взаимодействует с клиентами посредством принципа запрос-ответ. Хотя сервлеты могут обслуживать любые запросы, они обычно используются для расширения веб-серверов.
Большинство необходимых для создания сервлетов классов и интерфейсов содержатся в пакетах javax.servlet
и javax.servlet.http
.
Основные методы сервлета:
public void init(ServletConfig config) throws ServletException
запускается сразу после загрузки сервлета в память;public ServletConfig getServletConfig()
возвращает ссылку на объект, который предоставляет доступ к информации о конфигурации сервлета;public String getServletInfo()
возвращает строку, содержащую информацию о сервлете, например: автор и версия сервлета;public void service(ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException
вызывается для обработки каждого запроса;public void destroy()
выполняется перед выгрузкой сервлета из памяти.
Текущая спецификация - Servlet 4.0 описана в JSR-369 и принята в июле 2017 году.
Что добавилось в спецификации Servlet 2.5, 3.0, 3.1, 4.0?
- версия 2.5 принята в сентябре 2005 года - Требует J2SE 5.0, поддержка аннотаций.
- версия 3.0 принята в декабре 2009 года - Pluggability, простота разработки, асинхронные сервлеты, безопасность, загрузка файлов.
- версия 3.1 принята в майе 2013 года - Неблокирующий ввод-вывод, поддержка нестандартных протоколов поверх HTTP
- версия 4.0 принята в июле 2017 года - HTTP/2, Server Push.
В чем заключаются преимущества технологии сервлетов над CGI (Common Gateway Interface)?
- Сервлеты предоставляют лучшую производительность обработки запросов и более эффективное использование памяти за счет использования преимущество многопоточности (на каждый запрос создается новая нить, что быстрее выделения памяти под новый объект для каждого запроса, как это происходит в CGI).
- Сервлеты, как платформа и система являются независимыми. Таким образом веб-приложение написанное с использованием сервлетов может быть запущена в любом контейнере сервлетов, реализующим этот стандарт и в любой операционной системе.
- Использование сервлетов повышает надежность программы, т.к. контейнер сервлетов самостоятельно заботится о жизненном цикле сервлетов (а значит и за утечками памяти), безопасности и сборщике мусора.
- Сервлеты относительно легки в изучении и поддержке, таким образом разработчику необходимо заботиться только о бизнес-логике приложения, а не внутренней реализации веб-технологий.
Что такое «контейнер сервлетов»?
Контейнер сервлетов — программа, представляющая собой сервер, который занимается системной поддержкой сервлетов и обеспечивает их жизненный цикл в соответствии с правилами, определёнными в спецификациях. Может работать как полноценный самостоятельный веб-сервер, быть поставщиком страниц для другого веб-сервера, или интегрироваться в Java EE сервер приложений.
Контейнер сервлетов обеспечивает обмен данными между сервлетом и клиентами, берёт на себя выполнение таких функций, как создание программной среды для функционирующего сервлета, идентификацию и авторизацию клиентов, организацию сессии для каждого из них.
Наиболее известные реализации контейнеров сервлетов:
- Apache Tomcat
- Jetty
- JBoss
- WildFly
- GlassFish
- IBM WebSphere
- Oracle Weblogic
Зачем нужны сервера приложений, если есть контейнеры сервлетов?
- Пулы соединений с БД
- Возможность периодического тестирования доступности СУБД и обновления соединения в случае восстановления после сбоев
- Замена прав доступа при подключении
- Балансировка нагрузки между несколькими СУБД, определение доступность или недоступность того или иного узла
- Защита пула соединений от некорректного кода в приложении, которое по недосмотру не возвращает соединения, просто отбирая его после какого-то таймаута.
- JMS
- Доступность сервера очередей сообщений “из-коробки”.
- Возможность кластеризации очередей, т.е. доступность построения распределенных очередей, расположенных сразу на нескольких серверах, что существенно увеличивает масштабируемость и доступность приложения
- Возможность миграции очередей - в случае падения одного из серверов, его очереди автоматически перемещаются на другой, сохраняя необработанные сообщения.
- В некоторых серверах приложений поддерживается Unit-of-Order - гарантированный порядок обработки сообщений, удовлетворяющих некоторым критериям.
- JTA Встроенная поддержка распределенных транзакций для обеспечения согласованности данных в разные СУБД или очереди.
- Безопасность
- Наличие множества провайдеров безопасности и аутентификации:
- во встроенном или внешнем LDAP-сервере
- в базе данных
- в различных Internet-directory (специализированных приложениях для управления правами доступа)
- Доступность Single-Sign-On (возможности разделения пользовательской сессии между приложениями) посредством Security Assertion Markup Language (SAML) 1/2 или Simple and Protected Negotiate (SPNEGO) и Kerberos: один из серверов выступает в роли базы для хранения пользователей, все другие сервера при аутентификации пользователя обращаются к этой базе.
- Возможность авторизации посредством протокола eXtensible Access Control Markup Language (XACML), позволяющего описывать довольно сложные политики (например, приложение доступно пользователю только в рабочее время).
- Кластеризация всего вышеперечисленного
- Наличие множества провайдеров безопасности и аутентификации:
- Масштабируемость и высокая доступность Для контейнера сервлетов обычно так же возможно настроить кластеризацию, но
она будет довольно примитивной, так как в случае его использования имеются следующие ограничения:
- Сложность передачи пользовательской сессии из одного центра обработки данных (ЦОД) в другой через Интернет
- Отсутствие возможности эффективно настроить репликации сессий на большом (состоящем из 40-50 экземпляров серверов) кластере
- Невозможность обеспечения миграции экземпляров приложения на другой сервер
- Недоступность механизмов автоматического мониторинга и реакции на ошибки
- Управляемость
- Присутствие единого центра управления, т.н. AdminServer и аналога NodeManager’а, обеспечивающего
- Возможность одновременного запуска нескольких экземпляров сервера
- Просмотр состояния запущенных экземпляров сервера, обработчиков той или иной очереди, на том или ином сервере, количества соединений с той или иной БД
- Присутствие единого центра управления, т.н. AdminServer и аналога NodeManager’а, обеспечивающего
- Административный канал и развертывание в промышленном режиме Некоторые сервера приложений позволяют включить так
называемый “административный канал” - отдельный порт, запросы по которому имеют приоритет.
- Просмотр состояния (выполняющихся транзакций, потоков, очередей) в случае недоступности (“зависания”) сервера
- Обновление приложений “на-лету”, без простоя:
- добавление на сервер новой версии приложения в “закрытом” режиме, пока пользователи продолжают работать со предыдущей
- тестирование корректности развертывания новой версии
- “скрытый” перевод на использование новой версии всех пользователей
Как контейнер сервлетов управляет жизненным циклом сервлета, когда и какие методы вызываются?
Контейнер сервлетов управляет четырьмя фазами жизненного цикла сервлета:
- Загрузка класса сервлета — когда контейнер получает запрос для сервлета, то происходит загрузка класса сервлета в память и вызов его конструктора без параметров.
- Инициализация класса сервлета — после того как класс загружен контейнер инициализирует объект
ServletConfig
для этого сервлета и внедряет его черезinit()
метод. Это и есть место где сервлет класс преобразуется из обычного класса в сервлет. - Обработка запросов — после инициализации сервлет готов к обработке запросов. Для каждого запроса клиента сервлет контейнер порождает новый поток и вызывает метод
service()
путем передачи ссылки на объекты ответа и запроса. - Удаление - когда контейнер останавливается или останавливается приложение, то контейнер сервлетов уничтожает классы сервлетов путем вызова
destroy()
метода.
Таким образом, сервлет создаётся при первом обращении к нему и живёт на протяжении всего времени работы приложения (в отличие от объектов классов, которые уничтожаются сборщиком мусора после того как они уже не используются) и весь жизненный цикл сервлета можно описать как последовательность вызова методов:
public void init(ServletConfig config)
– используется контейнером для инициализации сервлета. Вызывается один раз за время жизни сервлета.public void service(ServletRequest request, ServletResponse response)
– вызывается для каждого запроса. Метод не может быть вызван раньше выполненияinit()
метода.public void destroy()
– вызывается для уничтожения сервлета (один раз за время жизни сервлета).
Что такое «дескриптор развертывания»?
Дескриптор развертывания — это конфигурационный файл артефакта, который будет развернут в контейнере сервлетов. В спецификации Java Platform, Enterprise Edition дескриптор развертывания описывает то, как компонент, модуль или приложение (такое, как веб-приложение или приложение предприятия) должно быть развернуто.
Этот конфигурационный файл указывает параметры развертывания для модуля или приложения с определенными настройками, параметры безопасности и описывает конкретные требования к конфигурации. Для синтаксиса файлов дескриптора развертывания используется язык XML.
Для веб-приложений дескриптор развертывания должен называться web.xml
и находиться в директории WEB-INF
, в корне веб-приложения. Этот файл является стандартным дескриптором развертывания, определенным в спецификации. Также есть и другие типы дескрипторов, такие, как файл дескриптора развертывания sun-web.xml
, содержащий специфичные для Sun GlassFish Enterprise Server данные для развертывания именно для этого сервера приложений или файл application.xml
в директории META-INF
для приложений J2EE.
Какие действия необходимо проделать при создании сервлетов?
Чтобы создать сервлет ExampleServlet
, необходимо описать его в дескрипторе развёртывания:
<servlet-mapping>
<servlet-name>ExampleServlet</servlet-name>
<url-pattern>/example</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ExampleServlet</servlet-name>
<servlet-class>xyz.company.ExampleServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>default</param-value>
</init-param>
</servlet>
Затем создать класс xyz.company.ExampleServlet
путём наследования от HttpServlet
и реализовать логику его работы в методе service()
или методах doGet()
/doPost()
.
Какие наиболее распространенные задачи выполняются в контейнере сервлетов?
- Поддержка обмена данными. Контейнер сервлетов предоставляет легкий способ обмена данными между веб клиентом (браузером) и сервлетом. Благодаря контейнеру нет необходимости создавать слушателя сокета на сервере для отслеживания запросов от клиента, а так же разбирать запрос и генерировать ответ. Все эти важные и комплексные задачи решаются с помощью контейнера и разработчик может сосредоточиться на бизнес логике приложения.
- Управление жизненным циклом сервлетов и ресурсов. Начиная от загрузки сервлета в память, инициализации, внедрения методов и заканчивая уничтожением сервлета. Контейнер так же предоставляет дополнительные утилиты, например JNDI, для управления пулом ресурсов.
- Поддержка многопоточности. Контейнер самостоятельно создает новую нить для каждого запроса и предоставляет ей запрос и ответ для обработки. Таким образом сервлет не инициализируется заново для каждого запроса и тем самым сохраняет память и уменьшает время до обработки запроса.
- Поддержка JSP. JSP классы не похожи на стандартные классы Java, но контейнер сервлетов преобразует каждую JSP в сервлет и далее управляется контейнером как обычным сервлетом.
- Различные задачи. Контейнер сервлетов управляет пулом ресурсов, памятью приложения, сборщиком мусора. Предоставляются возможности настройки безопасности и многое другое.
Что вы знаете о сервлетных фильтрах?
Сервлетный фильтр - это Java-код, пригодный для повторного использования и позволяющий преобразовать содержание HTTP-запросов, HTTP-ответов и информацию, содержащуюся в заголовках HTML. Сервлетный фильтр занимается предварительной обработкой запроса, прежде чем тот попадает в сервлет, и/или последующей обработкой ответа, исходящего из сервлета.
Сервлетные фильтры могут:
- перехватывать инициацию сервлета прежде, чем сервлет будет инициирован;
- определить содержание запроса прежде, чем сервлет будет инициирован;
- модифицировать заголовки и данные запроса, в которые упаковывается поступающий запрос;
- модифицировать заголовки и данные ответа, в которые упаковывается получаемый ответ;
- перехватывать инициацию сервлета после обращения к сервлету.
Когда стоит использовать фильтры сервлетов, а когда слушателей?
Следует использовать фильтры, если необходимо обрабатывать входящие или исходящие данные (например: для аутентификации, преобразования формата, компрессии, шифрования и т.д.), в случае, когда необходимо реагировать на события - лучше применять слушателей.
Какие основные особенности появились в спецификации Servlet 3?
- Servlet Annotations. До Servlet 3 вся конфигурация содержалась в
web.xml
, что приводило к ошибкам и неудобству при работе с большим количестве сервлетов. Примеры аннотаций:@WebServlet
,@WebInitParam
,@WebFilter
,@WebListener
. - Web Fragments. Одностраничное веб приложение может содержать множество модулей: все модули прописываются в
fragment.xml
в папкеMETA-INF\
. Это позволяет разделять веб приложение на отдельные модули, собранные как .jar-файлы в отдельнойlib\
директории. - Динамическое добавление веб компонентов. Появилась возможность программно добавлять фильтры и слушатели, используя
ServletContext
объект. Для этого применяются методыaddServlet()
,addFilter()
,addListener()
. Используя это нововведение стало доступным построение динамической системы, в которой необходимый объект будет создан и вызван только по необходимости. - Асинхронное выполнение. Поддержка асинхронной обработки позволяет передать выполнение запроса в другой поток без удержания всего сервера занятым.
Какие способы аутентификации доступны сервлету?
Спецификация сервлетов определяет четыре типа проверки подлинности:
- HTTP Basic Authentication -
BASIC
. При доступе к закрытым ресурсам появится окно, которое попросит ввести данные для аутентификации. - Form Based Login -
FORM
. Используется собственная html форма: - HTTP Digest Authentication -
DIGEST
. Цифровая аутентификация с шифрованием. - HTTPS Authentication -
CLIENT-CERT
. Аутентификация с помощью клиентского сертификата.
Что такое Java Server Pages (JSP)?
JSP (JavaServer Pages) — платформонезависимая переносимая и легко расширяемая технология разработки веб-приложений, позволяющая веб-разработчикам создавать содержимое, которое имеет как статические, так и динамические компоненты. Страница JSP содержит текст двух типов: статические исходные данные, которые могут быть оформлены в одном из текстовых форматов HTML, SVG, WML, или XML, и JSP-элементы, которые конструируют динамическое содержимое. Кроме этого могут использоваться библиотеки JSP-тегов, а также EL (Expression Language), для внедрения Java-кода в статичное содержимое JSP-страниц. Код JSP-страницы транслируется в Java-код сервлета с помощью компилятора JSP-страниц Jasper, и затем компилируется в байт-код JVM. JSP-страницы загружаются на сервере и управляются Java EE Web Application. Обычно такие страницы упакованы в файловые архивы .war и .ear.
Зачем нужен JSP?
JSP расширяет технологию сервлетов обеспечивая возможность создания динамических страницы с HTML подобным синтаксисом. Хотя создание представлений поддерживается и в сервлетах, но большая часть любой веб-страницы является статической, поэтому код сервлета в таком случае получается чересчур перегруженным, замусоренным и поэтому при его написании легко допустить ошибку. Еще одним преимуществом JSP является горячее развертывание - возможность заменить одну страницу на другую непосредственно в контейнере без необходимости перекомпилировать весь проект или перезапускать сервер. Однако рекомендуется избегать написания серьёзной бизнес-логики в JSP и использовать страницу только в качестве представления.
Взаимодействие JSP - сервлет - JSP
«JSP - сервлет - JSP» архитектура построения приложений носит название MVC (Model/View/Controller):
- Model - классы данных и бизнес-логики;
- View - страницы JSP;
- Controller - сервлеты.
Опишите общие практические принципы работы с JSP
Хорошей практикой работы с технологией JSP является соблюдение следующих правил:
- Следует избегать использования элементов скриптлетов на странице. Если элементы action, JSTL, JSP EL не удовлетворяют потребностям, то желательно написать собственный тег.
- Рекомендуется использовать разные виды комментариев: так JSP комментарии необходимы для уровня кода и отладки, т.к. они не будут показаны клиенту.
- Не стоит размещать какой-либо бизнес логики внутри JSP страницы. Страницы должны использоваться только для создания ответов клиенту.
- Для повышения производительности лучше отключать создание сессии на странице, когда это не требуется.
- Директивы
taglib
,page
в начале JSP страницы улучшают читабельность кода. - Следует правильно использовать директиву
include
и элементjsp:include action
. Первая используется для статических ресурсов, а второй для динамических ресурсов времени выполнения. - Обработку исключений нужно производить с помощью страниц ошибок. Это помогает избегать запуска специальных служебных методов и может повысить производительность.
- Использующиеся CSS и JavaScript должны быть разнесены в разные файлы и подключаться в начале страницы.
- В большинстве случаев JSTL должно хватать для всех нужд. Если это не так, то в начале следует проанализировать логику своего приложения, и попробовать перенести выполнения кода в сервлет, а далее с помощью установки атрибутов использовать на JSP странице только результат.