# Cобеседование по Java. Разбор вопросов и ответов.


<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
    <img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />        
  </a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
    <img src="https://mc.yandex.ru/watch/92801430" />        
  </a>&nbsp;&nbsp;


Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.

Если вам интересно мое резюме: https://github.com/DEBAGanov

[Вопросы для собеседования](README.md)

# Servlets, JSP, JSTL
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Servlets, JSP, JSTL](#servlets-jsp-jstl)
  - [Что такое _«сервлет»_?](#что-такое-сервлет)
  - [В чем заключаются преимущества технологии сервлетов над CGI (Common Gateway Interface)?](#в-чем-заключаются-преимущества-технологии-сервлетов-над-cgi-common-gateway-interface)
  - [Какова структура веб-проекта?](#какова-структура-веб-проекта)
  - [Что такое _«контейнер сервлетов»_?](#что-такое-контейнер-сервлетов)
  - [Зачем нужны сервера приложений, если есть контейнеры сервлетов?](#зачем-нужны-сервера-приложений-если-есть-контейнеры-сервлетов)
  - [Как контейнер сервлетов управляет жизненным циклом сервлета, когда и какие методы вызываются?](#как-контейнер-сервлетов-управляет-жизненным-циклом-сервлета-когда-и-какие-методы-вызываются)
  - [Что такое _«дескриптор развертывания»_?](#что-такое-дескриптор-развертывания)
  - [Какие действия необходимо проделать при создании сервлетов?](#какие-действия-необходимо-проделать-при-создании-сервлетов)
  - [В каком случае требуется переопределять метод `service()`?](#в-каком-случае-требуется-переопределять-метод-service)
  - [Есть ли смысл определять для сервлета конструктор? Каким образом лучше инициализировать данные?](#есть-ли-смысл-определять-для-сервлета-конструктор-каким-образом-лучше-инициализировать-данные)
  - [Почему необходимо переопределить только `init()` метод без аргументов?](#почему-необходимо-переопределить-только-init-метод-без-аргументов)
  - [Какие наиболее распространенные задачи выполняются в контейнере сервлетов?](#какие-наиболее-распространенные-задачи-выполняются-в-контейнере-сервлетов)
  - [Что вы знаете о _сервлетных фильтрах_?](#что-вы-знаете-о-сервлетных-фильтрах)
  - [Зачем в сервлетах используются различные _listener_?](#зачем-в-сервлетах-используются-различные-listener)
  - [Когда стоит использовать фильтры сервлетов, а когда слушателей?](#когда-стоит-использовать-фильтры-сервлетов-а-когда-слушателей)
  - [Как реализовать запуск сервлета одновременно с запуском приложения?](#как-реализовать-запуск-сервлета-одновременно-с-запуском-приложения)
  - [Как обработать в приложении исключения, выброшенные другим сервлетом?](#как-обработать-в-приложении-исключения-выброшенные-другим-сервлетом)
  - [Что представляет собой `ServletConfig`?](#что-представляет-собой-servletconfig)
  - [Что представляет собой `ServletContext`?](#что-представляет-собой-servletcontext)
  - [В чем отличия `ServletContext` и `ServletConfig`?](#в-чем-отличия-servletcontext-и-servletconfig)
  - [Для чего нужен интерфейс `ServletResponse`?](#для-чего-нужен-интерфейс-servletresponse)
  - [Для чего нужен интерфейс `ServletRequest`?](#для-чего-нужен-интерфейс-servletrequest)
  - [Что такое `Request Dispatcher`?](#что-такое-request-dispatcher)
  - [Как из одного сервлета вызвать другой сервлет?](#как-из-одного-сервлета-вызвать-другой-сервлет)
  - [Чем отличается `sendRedirect()` от `forward()`?](#чем-отличается-sendredirect-от-forward)
  - [Для чего используются атрибуты сервлетов и как происходит работа с ними?](#для-чего-используются-атрибуты-сервлетов-и-как-происходит-работа-с-ними)
  - [Каким образом можно допустить в сервлете deadlock?](#каким-образом-можно-допустить-в-сервлете-deadlock)
  - [Как получить реальное расположение сервлета на сервере?](#как-получить-реальное-расположение-сервлета-на-сервере)
  - [Как получить информацию о сервере из сервлета?](#как-получить-информацию-о-сервере-из-сервлета)
  - [Как получить IP адрес клиента на сервере?](#как-получить-ip-адрес-клиента-на-сервере)
  - [Какие классы-обертки для сервлетов вы знаете?](#какие-классы-обертки-для-сервлетов-вы-знаете)
  - [В чем отличия `GenericServlet` и `HttpServlet`?](#в-чем-отличия-genericservlet-и-httpservlet)
  - [Почему `HttpServlet` класс объявлен как абстрактный?](#почему-httpservlet-класс-объявлен-как-абстрактный)
  - [Какие основные методы присутствуют в классе `HttpServlet`?](#какие-основные-методы-присутствуют-в-классе-httpservlet)
  - [Стоит ли волноваться о многопоточной безопасности работая с сервлетами?](#стоит-ли-волноваться-о-многопоточной-безопасности-работая-с-сервлетами)
  - [Какой метод HTTP не является неизменяемым?](#какой-метод-http-не-является-неизменяемым)
  - [Какие есть методы отправки данных с клиента на сервер?](#какие-есть-методы-отправки-данных-с-клиента-на-сервер)
  - [В чем разница между методами `GET` и `POST`?](#в-чем-разница-между-методами-get-и-post)
  - [В чем разница между `PrintWriter` и `ServletOutputStream`?](#в-чем-разница-между-printwriter-и-servletoutputstream)
  - [Можно ли одновременно использовать в сервлете `PrintWriter` и `ServletOutputStream`?](#можно-ли-одновременно-использовать-в-сервлете-printwriter-и-servletoutputstream)
  - [Расскажите об интерфейсе `SingleThreadModel`.](#расскажите-об-интерфейсе-singlethreadmodel)
  - [Что означает _URL encoding_? Как это осуществить в Java?](#что-означает-url-encoding-как-это-осуществить-в-java)
  - [Какие различные методы управления сессией в сервлетах вы знаете?](#какие-различные-методы-управления-сессией-в-сервлетах-вы-знаете)
  - [Что такое _cookies_?](#что-такое-cookies)
  - [Какие методы для работы с cookies предусмотрены в сервлетах?](#какие-методы-для-работы-с-cookies-предусмотрены-в-сервлетах)
  - [Что такое _URL Rewriting_?](#что-такое-url-rewriting)
  - [Зачем нужны и чем отличаются методы `encodeURL()` и `encodeRedirectURL()`?](#зачем-нужны-и-чем-отличаются-методы-encodeurl-и-encoderedirecturl)
  - [Что такое _«сессия»_?](#что-такое-сессия)
  - [Как уведомить объект в сессии, что сессия недействительна или закончилась?](#как-уведомить-объект-в-сессии-что-сессия-недействительна-или-закончилась)
  - [Какой существует эффективный способ удостоверится, что все сервлеты доступны только для пользователя с верной сессией?](#какой-существует-эффективный-способ-удостоверится-что-все-сервлеты-доступны-только-для-пользователя-с-верной-сессией)
  - [Как мы можем обеспечить _transport layer security_ для нашего веб приложения?](#как-мы-можем-обеспечить-transport-layer-security-для-нашего-веб-приложения)
  - [Как организовать подключение к базе данных, обеспечить журналирование в сервлете?](#как-организовать-подключение-к-базе-данных-обеспечить-журналирование-в-сервлете)
  - [Какие основные особенности появились в спецификации _Servlet 3_?](#какие-основные-особенности-появились-в-спецификации-servlet-3)
  - [Какие способы аутентификации доступны сервлету?](#какие-способы-аутентификации-доступны-сервлету)
  - [Что такое _Java Server Pages (JSP)_?](#что-такое-java-server-pages-jsp)
  - [Зачем нужен JSP?](#зачем-нужен-jsp)
  - [Опишите, как обрабатываются JSP страницы, начиная от запроса к серверу, заканчивая ответом пользователю.](#опишите-как-обрабатываются-jsp-страницы-начиная-от-запроса-к-серверу-заканчивая-ответом-пользователю)
  - [Расскажите об этапах (фазах) жизненного цикла JSP.](#расскажите-об-этапах-фазах-жизненного-цикла-jsp)
  - [Расскажите о методах жизненного цикла JSP.](#расскажите-о-методах-жизненного-цикла-jsp)
  - [Какие методы жизненного цикла JSP могут быть переопределены?](#какие-методы-жизненного-цикла-jsp-могут-быть-переопределены)
  - [Как можно предотвратить прямой доступ к JSP странице из браузера?](#как-можно-предотвратить-прямой-доступ-к-jsp-странице-из-браузера)
  - [Какая разница между _динамическим_ и _статическим_ содержимым JSP?](#какая-разница-между-динамическим-и-статическим-содержимым-jsp)
  - [Как закомментировать код в JSP?](#как-закомментировать-код-в-jsp)
  - [Какие существуют основные типы тегов JSP?](#какие-существуют-основные-типы-тегов-jsp)
  - [Что вы знаете о действиях JSP (_Action tag_ и _JSP Action Elements_).](#что-вы-знаете-о-действиях-jsp-action-tag-и-jsp-action-elements)
  - [Взаимодействие _JSP - сервлет - JSP_.](#взаимодействие-jsp---сервлет---jsp)
  - [Какие области видимости переменных существуют в JSP?](#какие-области-видимости-переменных-существуют-в-jsp)
  - [Какие неявные, внутренние объекты и методы есть на JSP странице?](#какие-неявные-внутренние-объекты-и-методы-есть-на-jsp-странице)
  - [Какие неявные объекты не доступны в обычной JSP странице?](#какие-неявные-объекты-не-доступны-в-обычной-jsp-странице)
  - [Что вы знаете о `PageContext` и какие преимущества его использования?](#что-вы-знаете-о-pagecontext-и-какие-преимущества-его-использования)
  - [Как сконфигурировать параметры инициализации для JSP?](#как-сконфигурировать-параметры-инициализации-для-jsp)
  - [Почему не рекомендуется использовать скриплеты (скриптовые элементы) в JSP?](#почему-не-рекомендуется-использовать-скриплеты-скриптовые-элементы-в-jsp)
  - [Можно ли определить класс внутри JSP страницы?](#можно-ли-определить-класс-внутри-jsp-страницы)
  - [Что вы знаете о Языке выражений JSP (JSP Expression Language – EL)?](#что-вы-знаете-о-языке-выражений-jsp-jsp-expression-language--el)
  - [Какие типы EL операторов вы знаете?](#какие-типы-el-операторов-вы-знаете)
  - [Назовите неявные, внутренние объекты JSP EL и их отличия от объектов JSP.](#назовите-неявные-внутренние-объекты-jsp-el-и-их-отличия-от-объектов-jsp)
  - [Как отключить возможность использования EL в JSP?](#как-отключить-возможность-использования-el-в-jsp)
  - [Как узнать тип HTTP метода используя JSP EL?](#как-узнать-тип-http-метода-используя-jsp-el)
  - [Что такое _JSTL (JSP Standard tag library)_?](#что-такое-jstl-jsp-standard-tag-library)
  - [Из каких групп тегов состоит библиотека _JSTL_?](#из-каких-групп-тегов-состоит-библиотека-jstl)
  - [Какая разница между `<c:set>` и `<jsp:useBean>`?](#какая-разница-между-cset-и-jspusebean)
  - [Чем отличается `<c:import>` от `<jsp:include>` и директивы `<%@include %>`?](#чем-отличается-cimport-от-jspinclude-и-директивы-include-)
  - [Как можно расширить функциональность JSP?](#как-можно-расширить-функциональность-jsp)
  - [Что вы знаете о написании пользовательских JSP тегов?](#что-вы-знаете-о-написании-пользовательских-jsp-тегов)
  - [Приведите пример использования собственных тегов.](#приведите-пример-использования-собственных-тегов)
  - [Как сделать перенос строки в HTML средствами JSP?](#как-сделать-перенос-строки-в-html-средствами-jsp)
  - [Почему не нужно конфигурировать стандартные JSP теги в `web.xml`?](#почему-не-нужно-конфигурировать-стандартные-jsp-теги-в-webxml)
  - [Как можно обработать ошибки JSP страниц?](#как-можно-обработать-ошибки-jsp-страниц)
  - [Как происходит обработка ошибок с помощью JSTL?](#как-происходит-обработка-ошибок-с-помощью-jstl)
  - [Как конфигурируется JSP в дескрипторе развертывания.](#как-конфигурируется-jsp-в-дескрипторе-развертывания)
  - [Можно ли использовать Javascript на JSP странице?](#можно-ли-использовать-javascript-на-jsp-странице)
  - [Всегда ли создается объект сессии на JSP странице, можно ли отключить его создание?](#всегда-ли-создается-объект-сессии-на-jsp-странице-можно-ли-отключить-его-создание)
  - [Какая разница между `JSPWriter` и сервлетным `PrintWriter`?](#какая-разница-между-jspwriter-и-сервлетным-printwriter)
  - [Опишите общие практические принципы работы с 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 3.1 описана в JSR-340 и принята в 2013 году.

[к оглавлению](#servlets-jsp-jstl)

## В чем заключаются преимущества технологии сервлетов над CGI (Common Gateway Interface)?
+ Сервлеты предоставляют лучшую производительность обработки запросов и более эффективное использование памяти за счет использования преимущество многопоточности (на каждый запрос создается новая нить, что быстрее выделения памяти под новый объект для каждого запроса, как это происходит в CGI).
+ Сервлеты, как платформа и система являются независимыми. Таким образом веб-приложение написанное с использованием сервлетов может быть запущена в любом контейнере сервлетов, реализующим этот стандарт и в любой операционной системе.
+ Использование сервлетов повышает надежность программы, т.к. контейнер сервлетов самостоятельно заботится о жизненном цикле сервлетов (а значит и за утечками памяти), безопасности и сборщике мусора.
+ Сервлеты относительно легки в изучении и поддержке, таким образом разработчику необходимо заботиться только о бизнес-логике приложения, а не внутренней реализации веб-технологий.

[к оглавлению](#servlets-jsp-jstl)

## Какова структура веб-проекта?
`src/main/java` Исходники приложения/библиотеки

`src/main/resources` Ресурсные файлы приложения/библиотеки

`src/main/filters` Файлы сервлетных фильтров

`src/main/webapp` Исходники веб-приложения

`src/test/java` Исходники тестов

`src/test/resources` Ресурсные файлы тестов

`src/test/filters` Тесты сервлетных фильтров

`src/it` Интеграционные тесты

`src/assembly` Описание сборки

`src/site` Сайт

`LICENSE.txt` Лицензия проекта

`NOTICE.txt` Замечания и определения библиотек зависимостей.

`README.txt` Описание проекта

[к оглавлению](#servlets-jsp-jstl)

## Что такое _«контейнер сервлетов»_?
__Контейнер сервлетов__ — программа, представляющая собой сервер, который занимается системной поддержкой сервлетов и обеспечивает их жизненный цикл в соответствии с правилами, определёнными в спецификациях. Может работать как полноценный самостоятельный веб-сервер, быть поставщиком страниц для другого веб-сервера, или интегрироваться в Java EE сервер приложений.

Контейнер сервлетов обеспечивает обмен данными между сервлетом и клиентами, берёт на себя выполнение таких функций, как создание программной среды для функционирующего сервлета, идентификацию и авторизацию клиентов, организацию сессии для каждого из них.

Наиболее известные реализации контейнеров сервлетов:

+ Apache Tomcat
+ Jetty
+ JBoss
+ WildFly
+ GlassFish
+ IBM WebSphere
+ Oracle Weblogic

[к оглавлению](#servlets-jsp-jstl)

## Зачем нужны сервера приложений, если есть контейнеры сервлетов?
+ __Пулы соединений с БД__ 
    + Возможность периодического тестирования доступности СУБД и обновления соединения в случае восстановления после сбоев
    + Замена прав доступа при подключении
    + Балансировка нагрузки между несколькими СУБД, определение доступность или недоступность того или иного узла
    + Защита пула соединений от некорректного кода в приложении, которое по недосмотру не возвращает соединения, просто отбирая его после какого-то таймаута.
+ __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_’а, обеспечивающего
        + Возможность одновременного запуска нескольких экземпляров сервера
        + Просмотр состояния запущенных экземпляров сервера, обработчиков той или иной очереди, на том или ином сервере, количества соединений с той или иной БД
+ __Административный канал и развертывание в промышленном режиме__ Некоторые сервера приложений позволяют включить так называемый "административный канал" - отдельный порт, запросы по которому имеют приоритет.
    + Просмотр состояния (выполняющихся транзакций, потоков, очередей) в случае недоступности ("зависания") сервера
    + Обновление приложений "на-лету", без простоя: 
        + добавление на сервер новой версии приложения в "закрытом" режиме, пока пользователи продолжают работать со предыдущей
        + тестирование корректности развертывания новой версии
        + "скрытый" перевод на использование новой версии всех пользователей

[к оглавлению](#servlets-jsp-jstl)

## Как контейнер сервлетов управляет жизненным циклом сервлета, когда и какие методы вызываются?
Контейнер сервлетов управляет четырьмя фазами жизненного цикла сервлета:

+ Загрузка класса сервлета — когда контейнер получает запрос для сервлета, то происходит загрузка класса сервлета в память и вызов его конструктора без параметров.
+ Инициализация класса сервлета — после того как класс загружен контейнер инициализирует объект `ServletConfig` для этого сервлета и внедряет его через `init()` метод. Это и есть место где сервлет класс преобразуется из обычного класса в сервлет.
+ Обработка запросов — после инициализации сервлет готов к обработке запросов. Для каждого запроса клиента сервлет контейнер порождает новый поток и вызывает метод `service()` путем передачи ссылки на объект ответы и запроса.
+ Удаление - когда контейнер останавливается или останавливается приложение, то контейнер сервлетов уничтожает классы сервлетов путем вызова `destroy()` метода.

Таким образом, сервлет создаётся при первом обращении к нему и живёт на протяжении всего времени работы приложения (в отличии от объекты классов, которые уничтожаются сборщиком мусора после того как они уже не используются) и весь жизненный цикл сервлета можно описать как последовательность вызова методов:

+ `public void init(ServletConfig config)` – используется контейнером для инициализации сервлета. Вызывается один раз за время жизни сервлета.
+ `public void service(ServletRequest request, ServletResponse response)` – вызывается для каждого запроса. Метод не может быть вызван раньше выполнения `init()` метода.
+ `public void destroy()` – вызывается для уничтожения сервлета (один раз за время жизни сервлета).

[к оглавлению](#servlets-jsp-jstl)

## Что такое _«дескриптор развертывания»_?
Дескриптор развертывания — это конфигурационный файл артефакта, который будет развернут в контейнере сервлетов. В спецификации Java Platform, Enterprise Edition дескриптор развертывания описывает то, как компонент, модуль или приложение (такое, как веб-приложение или приложение предприятия) должно быть развернуто.

Этот конфигурационный файл указывает параметры развертывания для модуля или приложения с определенными настройками, параметры безопасности и описывает конкретные требования к конфигурации. Для синтаксиса файлов дескриптора развертывания используется язык XML.

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <display-name>Display name.</display-name>
    <description>Description text.</description>

    <servlet>
        <servlet-name>ExampleServlet</servlet-name>
        <servlet-class>xyz.company.ExampleServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>configuration</param-name>
            <param-value>default</param-value>
        </init-param>       
    </servlet>

    <servlet-mapping>
        <servlet-name>ExampleServlet</servlet-name>
        <url-pattern>/example</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ExampleJSP</servlet-name>
        <jsp-file>/sample/Example.jsp</jsp-file>
    </servlet>

    <context-param>
        <param-name>myParam</param-name>
        <param-value>the value</param-value>
    </context-param>
</web-app>
```

Для веб-приложений дескриптор развертывания должен называться `web.xml` и находиться в директории `WEB-INF`, в корне веб-приложения. Этот файл является стандартным дескриптором развертывания, определенным в спецификации. Также есть и другие типы дескрипторов, такие, как файл дескриптора развертывания `sun-web.xml`, содержащий специфичные для _Sun GlassFish Enterprise Server_ данные для развертывания именно для этого сервера приложений или файл `application.xml` в директории `META-INF` для приложений _J2EE_.

[к оглавлению](#servlets-jsp-jstl)

## Какие действия необходимо проделать при создании сервлетов?
Чтобы создать сервлет `ExampleServlet`, необходимо описать его в дескрипторе развёртывания:

```xml
<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()`.

[к оглавлению](#servlets-jsp-jstl)

## В каком случае требуется переопределять метод `service()`?
Метод `service()` переопределяется, когда необходимо, чтобы сервлет обрабатывал все запросы (и `GET`, и `POST`) в одном методе.

Когда контейнер сервлетов получает запрос клиента, то происходит вызов метода `service()`, который в зависимости от поступившего запроса вызывает или метод `doGet()` или метод `doPost()`.

[к оглавлению](#servlets-jsp-jstl)

## Есть ли смысл определять для сервлета конструктор? Каким образом лучше инициализировать данные?
Большого смысла определять для сервлета конструктор нет, т.к. инициализировать данные лучше не в конструкторе, а переопределив метод `init()`, в котором имеется возможность доступа к параметрам инициализации сервлета через использование объекта `ServletConfig`.

[к оглавлению](#servlets-jsp-jstl)

## Почему необходимо переопределить только `init()` метод без аргументов?
Метод `init()` переопределяется, если необходимо инициализировать какие-то данные до того как сервлет начнет обрабатывать запросы. 

При переопределении метода `init(ServletConfig config)`, первым должен быть вызван метод `super(config)`, который обеспечит вызов метода `init(ServletConfig config)` суперкласса. `GenericServlet` предоставляет другой метод `init()` без параметров, который будет вызываться в конце метода `init(ServletConfig config)`.

Необходимо использовать переопределенный метод `init()` без параметров для инициализации данных во избежание каких-либо проблем, например ошибку, когда вызов `super()` не указан в переопределенном `init(ServletConfig config)`.

[к оглавлению](#servlets-jsp-jstl)

## Какие наиболее распространенные задачи выполняются в контейнере сервлетов?
+ Поддержка обмена данными. Контейнер сервлетов предоставляет легкий способ обмена данными между веб клиентом (браузером) и сервлетом. Благодаря контейнеру нет необходимости создавать слушателя сокета на сервере для отслеживания запросов от клиента, а так же разбирать запрос и генерировать ответ. Все эти важные и комплексные задачи решаются с помощью контейнера и разработчик может сосредоточиться на бизнес логике приложения.
+ Управление жизненным циклом сервлетов и ресурсов. Начиная от загрузки сервлета в память, инициализации, внедрения методов и заканчивая уничтожением сервлета. Контейнер так же предоставляет дополнительные утилиты, например JNDI, для управления пулом ресурсов.
+ Поддержка многопоточности. Контейнер самостоятельно создает новую нить для каждого запроса и предоставляет ей запрос и ответ для обработки. Таким образом сервлет не инициализируется заново для каждого запроса и тем самым сохраняет память и уменьшает время до обработки запроса.
+ Поддержка JSP. JSP классы не похожи на стандартные классы джавы, но контейнер сервлетов преобразует каждую JSP в сервлет и далее управляется контейнером как обычным сервлетом.
+ Различные задачи. Контейнер сервлетов управляет пулом ресурсов, памятью приложения, сборщиком мусора. Предоставляются возможности настройки безопасности и многое другое.

[к оглавлению](#servlets-jsp-jstl)

## Что вы знаете о _сервлетных фильтрах_?
__Сервлетный фильтр__ - это Java-код, пригодный для повторного использования и позволяющий преобразовать содержание HTTP-запросов, HTTP-ответов и информацию, содержащуюся в заголовках HTML. Сервлетный фильтр занимается предварительной обработкой запроса, прежде чем тот попадает в сервлет, и/или последующей обработкой ответа, исходящего из сервлета.

Сервлетные фильтры могут:

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

Сервлетный фильтр может быть конфигурирован так, что он будет работать с одним сервлетом или группой сервлетов. Основой для формирования фильтров служит интерфейс `javax.servlet.Filter`, который реализует три метода:

+ `void init(FilterConfig config) throws ServletException`;
+ `void destroy()`;
+ `void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException`;

Метод `init()` вызывается прежде, чем фильтр начинает работать,и настраивает конфигурационный объект фильтра. Метод `doFilter()` выполняет непосредственно работу фильтра. Таким образом, сервер вызывает `init()` один раз, чтобы запустить фильтр в работу, а затем вызывает `doFilter()` столько раз, сколько запросов будет сделано непосредственно к данному фильтру. После того, как фильтр заканчивает свою работу, вызывается метод `destroy()`.

Интерфейс `FilterConfig` содержит метод для получения имени фильтра, его параметров инициации и контекста активного в данный момент сервлета. С помощью своего метода `doFilter()` каждый фильтр получает текущий запрос `request` и ответ `response`, а также `FilterChain`, содержащий список фильтров, предназначенных для обработки. В `doFilter()` фильтр может делать с запросом и ответом всё, что ему захочется - собирать данные или упаковывать объекты для придания им нового поведения. Затем фильтр вызывает `chain.doFilter()`, чтобы передать управление следующему фильтру. После возвращения этого вызова фильтр может по окончании работы своего метода `doFilter()` выполнить дополнительную работу над полученным ответом. К примеру, сохранить регистрационную информацию об этом ответе.

После того, как класс-фильтр откомпилирован, его необходимо установить в контейнер и _«приписать» (map)_ к одному или нескольким сервлетам. Объявление и подключение фильтра отмечается в дескрипторе развёртывания `web.xml` внутри элементов <filter> и <filter-mapping>. Для подключение фильтра к сервлету необходимо использовать вложенные элементы <filter-name> и <servlet-name>.

> Объявление класс-фильтра `FilterConnect` с именем `FilterName`:

```xml
  <filter>
        <filter-name>FilterName</filter-name>
        <filter-class>FilterConnect</filter-class>
        <init-param>
                <!--- фильтр имеет параметр инициализации `active`, которому присваивается значение `true`. -->
                <param-name>active</param-name>
                <param-value>true</param-true>
        </init-param>
  </filter>
```

> Подключение фильтра `FilterName` к сервлету `ServletName`:

```xml
  <filter-mapping>
        <filter-name>FilterName</filter-name>
        <servlet-name>ServletName</servlet-name>
  </filter-mapping>
```

Для связи фильтра со страницами HTML или группой сервлетов необходимо использовать тег `<url-pattern>`:

> Подключение фильтра `FilterName` ко всем вызовам .html страниц

```xml
  <filter-mapping>
          <filter-name>FilterName</filter-name>
          <url-pattern>*.html</url-pattern>
  </filter-mapping>
```

Порядок, в котором контейнер строит цепочку фильтров для запроса определяется следующими правилами:

+ цепочка, определяемая `<url-pattern>`, выстраивается в том порядке, в котором встречаются соответствующие описания фильтров в `web.xml`;
+ последовательность сервлетов, определенных с помощью `<servlet-name>`, также выполняется в той последовательности, в какой эти элементы встречаются в дескрипторе развёртывания `web.xml`.

[к оглавлению](#servlets-jsp-jstl)

## Зачем в сервлетах используются различные _listener_?
__Listener (слушатель)__ работает как триггер, выполняя определённые действия при наступлении какого-либо события в жизненном цикле сервлета.

Слушатели, разделённые по области видимости (scope):

+ _Request_:
    + `ServletRequestListener` используется для того, чтобы поймать момент создания и уничтожения запроса;
    + `ServletRequestAttributeListener` используется для прослушивании событий происходящих с атрибутами запроса.
+ _Context_:
    + `ServletContextListener` позволяет поймать момент, когда контекст инициализируется либо уничтожается;
    + `ServletContextAttributeListener` используется для прослушивании событий происходящих с атрибутами в контексте.
+ _Session_:
    + `HttpSessionListener` позволяет поймать момент создания и уничтожения сессии;
    + `HttpSessionAttributeListener` используется при прослушивании событий происходящих с атрибутами в сессии;
    + `HttpSessionActivationListener` используется в случае, если происходит миграция сессии между различными JVM в распределённых приложениях;
    + `HttpSessionBindingListener` так же используется для прослушивания событий происходящих с атрибутами в сессии. Разница между `HttpSessionAttributeListener` и `HttpSessionBindingListener` слушателями: первый декларируется в `web.xml`; экземпляр класса создается контейнером автоматически в единственном числе и применяется ко всем сессиям; второй: экземпляр класса должен быть создан и закреплён за определённой сессией «вручную», количество экземпляров также регулируется самостоятельно.

Подключение слушателей:

```xml
<web-app>
    ...
    <listener>
        <listener-class>xyz.company.ExampleListener</listener-class>
    </listener>
    ...
</web-app>
```

`HttpSessionBindingListener` подключается в качестве атрибута непосредственно в сессию, т.е., чтобы его подключить необходимо:

+ создать экземпляр класса реализующего этот интерфейс;
+ положить созданный экземпляр в сессию при помощи `setAttribute(String, Object)`.

[к оглавлению](#servlets-jsp-jstl)

## Когда стоит использовать фильтры сервлетов, а когда слушателей?
Следует использовать фильтры, если необходимо обрабатывать входящие или исходящие данные (например: для аутентификации, преобразования формата, компрессии, шифрования и т.д.), в случае, когда необходимо реагировать на события - лучше применять слушателей.

[к оглавлению](#servlets-jsp-jstl)

## Как реализовать запуск сервлета одновременно с запуском приложения?
Контейнер сервлетов обычно загружает сервлет по первому запросу клиента.

Если необходимо загрузить сервлет прямо на старте приложения (например если загрузка сервлета происходит длительное время) следует использовать элемент `<load-on-startup>` в дескрипторе или аннотацию `@loadOnStartup` в коде сервлета, что будет указывать на необходимость загрузки сервлета при запуске.

Если целочисленное значение этого параметра отрицательно, то сервлет будет загружен при запросе клиента. В противном случае - загрузится на старте приложения, при этом, чем число меньше, тем раньше в очереди на загрузку он окажется.

```xml
<servlet>
    <servlet-name>ExampleServlet</servlet-name>
    <servlet-class>xyz.company.ExampleServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
```

[к оглавлению](#servlets-jsp-jstl)

## Как обработать в приложении исключения, выброшенные другим сервлетом?
Когда приложение выбрасывет исключение контейнер сервлетов обрабатывает его и создаёт ответ в формате HTML. Это аналогично тому что происходит при кодах ошибок вроде 404, 403 и т.д.

В дополнении к этому существует возможность написания собственных сервлетов для обработки исключений и ошибок с указанием их в дескрипторе развертывания:

```xml
<error-page>
    <error-code>404</error-code>
    <location>/AppExceptionHandler</location>
</error-page>

<error-page>
    <exception-type>javax.servlet.ServletException</exception-type>
    <location>/AppExceptionHandler</location>
</error-page>
```

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

[к оглавлению](#servlets-jsp-jstl)

## Что представляет собой `ServletConfig`?
Интерфейс `javax.servlet.ServletConfig` используется для передачи сервлету конфигурационной информации. Каждый сервлет имеет свой собственный экземпляр объекта `ServletConfig`, создаваемый контейнером сервлетов.

Для установки параметров конфигурации используются параметры `init-param` в `web.xml`:

```xml
<servlet>
    <servlet-name>ExampleServlet</servlet-name>
    <servlet-class>xyz.company.ExampleServlet</servlet-class>
    <init-param>
        <param-name>exampleParameter</param-name>
        <param-value>parameterValue</param-value>
    </init-param>
</servlet>
```

или аннотации `@WebInitParam`:

```java
@WebServlet(
    urlPatterns = "/example",
    initParams = {
        @WebInitParam(name = "exampleParameter", value = "parameterValue")
    }
)
public class ExampleServlet extends HttpServlet {
    //...
}
```

Для получения `ServletConfig` сервлета используется метод `getServletConfig()`.

[к оглавлению](#servlets-jsp-jstl)

## Что представляет собой `ServletContext`?
Уникальный (в рамках веб-приложения) объект `ServletContext` реализует интерфейс `javax.servlet.ServletContext` и предоставляет сервлетам доступ к параметрам этого веб-приложения.  Для предоставления доступа используется элемент `<context-param>` в `web.xml`:

```xml
<web-app>
    ...
    <context-param>
        <param-name>exampleParameter</param-name>
        <param-value>parameterValue</param-value>
    </context-param>
    ...
</web-app>
```

Объект `ServletContext` можно получить с помощью метода `getServletContext()` у интерфейса `ServletConfig`. Контейнеры сервлетов так же могут предоставлять контекстные объекты, уникальные для группы сервлетов. Каждая из групп будет связана со своим набором URL-путей хоста. В спецификации Servlet 3 `ServletContext` был расширен и теперь предоставляет возможности программного добавления слушателей и фильтров в приложение. Так же у этого интерфейса имеется множество полезных методов таких как 	`getServerInfo()`, `getMimeType()`, `getResourceAsStream()` и т.д.

[к оглавлению](#servlets-jsp-jstl)


## В чем отличия `ServletContext` и `ServletConfig`?
+ `ServletConfig` уникален для сервлета, а `ServletContext` - для приложения;
+ `ServletConfig` используется для предоставления параметров инициализации конкретному сервлету, а `ServletContext` для предоставления параметров инициализации для всех сервлетов приложения;
+ для `ServletConfig` возможности модифицировать атрибуты отсутствуют, атрибуты в объекте `ServletContext` можно изменять.

[к оглавлению](#servlets-jsp-jstl)

## Для чего нужен интерфейс `ServletResponse`?
Интерфейс `ServletResponse` используется для отправки данных клиенту. Все методы данного инструмента служат именно этой цели:

+ `String getCharacterEncoding()` - возвращает MIME тип кодировки (к примеру - UTF8), в которой будет выдаваться информация;
+ `void setLocale(Locale locale)`/`Locale getLocale()` - указывают на язык используемый в документе;
+ `ServletOutputStream getOutputStream()`/`PrintWriter getWriter()` - возвращают потоки вывода данных;
+ `void setContentLength(int len)` - устанавливает значение поля HTTP заголовка _Content-Length_;
+ `void setContentType(String type)` - устанавливает значение поля HTTP заголовка _Content-Type_.
+ `void reset()` - позволяет сбрасить HTTP заголовок к значениям по-умолчанию, если он ещё не был отправлен
+ и др.

[к оглавлению](#servlets-jsp-jstl)

## Для чего нужен интерфейс `ServletRequest`?
Интерфейс `ServletRequest` используется для получения параметров соединения, запроса, а также заголовков, входящего потока данных и т.д.

[к оглавлению](#servlets-jsp-jstl)

## Что такое `Request Dispatcher`?
Интерфейс `RequestDispatcher` используется для передачи запроса другому ресурсу, при этом существует возможность добавления данных полученных из этого ресурса к собственному ответу сервлета. Так же этот интерфейс используется для внутренней коммуникации между сервлетами в одном контексте.

В интерфейса реализовано два метода:

+ `void forward(ServletRequest var1, ServletResponse var2)` — передает запрос из сервлета к другому ресурсу (сервлету, JSP или HTML файлу) на сервере.
+ `void include(ServletRequest var1, ServletResponse var2)` — включает контент ресурса (сервлет, JSP или HTML страница) в ответ.

Доступ к интерфейсу можно получить с помощью метода интерфейса `ServletContext` - `RequestDispatcher getRequestDispatcher(String path)`, где путь начинающийся с `/`, интерпретируется относительно текущего корневого пути контекста.

[к оглавлению](#servlets-jsp-jstl)

## Как из одного сервлета вызвать другой сервлет?
Для вызова сервлета из того же приложения необходимо использовать механизм внутренней коммуникации сервлетов (_inter-servlet communication mechanisms_) через вызовы методов `RequestDispatcher`: 

+ `forward()` - передаёт выполнение запроса в другой сервлет;
+ `include()` - предоставляет возможность включить результат работы другого сервлета в возвращаемый ответ.

Если необходимо вызывать сервлет принадлежащий другому приложению, то использовать `RequestDispatcher` уже не получится, т.к. он определен только для текущего приложения. Для подобных целей необходимо использовать метод `ServletResponse` - `sendRedirect()` которому предоставляется полный URL другого сервлета. Для передачи данных между сервлетами можно использовать `cookies`.

[к оглавлению](#servlets-jsp-jstl)

## Чем отличается `sendRedirect()` от `forward()`?
__`forward()`__:

+ Выполняется на стороне сервера;
+ Запрос перенаправляется на другой ресурс в пределах того же сервера;
+ Не зависит от протокола клиентского запроса клиента, так как обеспечивается контейнером сервлетов;
+ Нельзя применять для внедрения сервлета в другой контекст;
+ Клиент не знает о фактически обрабатываемом ресурсе и URL в строке остается прежним;
+ Выполняется быстрее метода `sendRedirect()`;
+ Определён в интерфейсе `RequestDispatcher`.

__`sendRedirect()`__:

+ Выполняется на стороне клиента;
+ Клиенту возвращается ответ `302 (redirect)` и запрос перенаправляется на другой сервер;
+ Может использоваться только с клиентами HTTP;
+ Разрешается применять для внедрения сервлета в другой контекст;
+ URL адрес изменяется на адрес нового ресурса;
+ Медленнее `forward()` т.к. требует создания нового запроса;
+ Определён в интерфейсе `HttpServletResponse`.

[к оглавлению](#servlets-jsp-jstl)

## Для чего используются атрибуты сервлетов и как происходит работа с ними?
Атрибуты сервлетов используются для внутренней коммуникации сервлетов.

В веб-приложении существует возможность работы с атрибутами используя методы `setAttribute()`, `getAttribute()`, `removeAttribute()`, `getAttributeNames()`, которые предоставлены интерфейсами `ServletRequest`, `HttpSession` и `ServletContext` (для областей видимости _request_, _session_, _context_ соответственно).

[к оглавлению](#servlets-jsp-jstl)

## Каким образом можно допустить в сервлете deadlock?
Можно получить блокировку, например, допустив циклические вызовы метода `doPost()` в методе `doGet()` и метода `doGet()` в методе `doPost()`.

[к оглавлению](#servlets-jsp-jstl)

## Как получить реальное расположение сервлета на сервере?
Реальный путь к расположению сервлета на сервере можно получить из объекта `ServletContext`: 

`getServletContext().getRealPath(request.getServletPath())`.

[к оглавлению](#servlets-jsp-jstl)

## Как получить информацию о сервере из сервлета?
Информацию о сервере можно получить из объекта `ServletContext`: 

`getServletContext().getServerInfo()`.

[к оглавлению](#servlets-jsp-jstl)

## Как получить IP адрес клиента на сервере?
IP адрес клиента можно получить вызвав `request.getRemoteAddr()`.

[к оглавлению](#servlets-jsp-jstl)

## Какие классы-обертки для сервлетов вы знаете?
Собственные обработчики `ServletRequest` и `ServletResponse` можно реализовать добавив новые или переопределив существующие методы у классов-обёрток `ServletRequestWrapper` (`HttpServletRequestWrapper`) и `ServletResponseWrapper` (`HttpServletRequestWrapper`).

[к оглавлению](#servlets-jsp-jstl)

## В чем отличия `GenericServlet` и `HttpServlet`?
Абстрактный класс `GenericServlet` — независимая от используемого протокола реализация интерфейса `Servlet`, а абстрактный класс `HttpServlet` в свою очередь расширяет `GenericServlet` для протокола HTTP..

[к оглавлению](#servlets-jsp-jstl)

## Почему `HttpServlet` класс объявлен как абстрактный?
Класс `HTTPServlet` предоставляет лишь общую реализацию сервлета для HTTP протокола. Реализация ключевых методов `doGet()` и `doPost()`, содержащих основную бизнес-логику перекладывается на разработчика и по умолчанию возвращает `HTTP 405 Method Not Implemented error`.

[к оглавлению](#servlets-jsp-jstl)

## Какие основные методы присутствуют в классе `HttpServlet`?
+ `doGet()` - для обработки HTTP запросов `GET`;
+ `doPost()` - для обработки HTTP запросов `POST`;
+ `doPut()` - для обработки HTTP запросов `PUT`;
+ `doDelete()` - для обработки HTTP запросов `DELETE`;
+ `doHead()` - для обработки HTTP запросов `HEAD`;
+ `doOptions()` - для обработки HTTP запросов `OPTIONS`;
+ `doTrace()` - для обработки HTTP запросов `TRACE`.

[к оглавлению](#servlets-jsp-jstl)

## Стоит ли волноваться о многопоточной безопасности работая с сервлетами?
Методы `init()` и `destroy()` вызываются один раз за жизненный цикл сервлета — поэтому по поводу них беспокоиться не стоит. 

Методы `doGet()`, `doPost()`, `service()` вызываются на каждый запрос клиента и т.к. сервлеты используют многопоточность, то здесь задумываться о потокобезопасной работе обязательноЮ при этом правила использования многопоточности остаются теми же: локальные переменные этих методов будут созданы отдельно для каждого потока, а при использовании глобальных разделяемых ресурсов необходимо использовать синхронизацию или другие приёмы многопоточного программирования.

[к оглавлению](#servlets-jsp-jstl)

## Какой метод HTTP не является неизменяемым?
HTTP метод называется неизменяемым, если он на один и тот же запрос всегда возвращает одинаковый результат. HTTP методы `GET`, `PUT`, `DELETE`, `HEAD` и `OPTIONS` являются неизменяемыми, поэтому необходимо реализовывать приложение так, чтобы эти методы возвращали одинаковый результат постоянно. К изменяемым методам относится метод `POST`, который и используется для реализации чего-либо, что изменяется при каждом запросе.

К примеру, для доступа к статической HTML странице используется метод `GET`, т.к. он всегда возвращает одинаковый результат. При необходимости сохранять какую-либо информацию, например в базе данных, нужно использовать `POST` метод.

[к оглавлению](#servlets-jsp-jstl)

## Какие есть методы отправки данных с клиента на сервер?
+ `GET` - используется для запроса содержимого указанного ресурса, изображения или гипертекстового документа. Вместе с за просом могут передаваться дополнительные параметры как часть URI, значения могут выбираться из полей формы или передаваться непосредственно через URL. При этом запросы кэшируются и имеют ограничения на размер. Этот метод является основным методом взаимодействия браузера клиента и веб-сервера. 
+ `POST` - используется для передачи пользовательских данных в содержимом HTTP-запроса на сервер. Пользовательские данные упакованы в тело запроса согласно полю заголовка Content-Type и/или включены в URI запроса. При использовании метода POST под URI подразумевается ресурс, который будет обрабатывать запрос. 

[к оглавлению](#servlets-jsp-jstl)

## В чем разница между методами `GET` и `POST`?
+ `GET` передает данные серверу используя URL, тогда как `POST` передает данные, используя тело HTTP запроса. Длина URL ограничена 1024 символами, это и будет верхним ограничением для данных, которые можно отослать через `GET`. `POST` может отправлять гораздо большие объемы данных. Лимит устанавливается web-server и составляет обычно около 2 Mb.
+ Передача данных методом `POST` более безопасна, чем методом `GET`, так как секретные данные (например пароль) не отображаются напрямую в web-клиенте пользователя, в отличии от URL, который виден почти всегда. Иногда это преимущество превращается в недостатком - вы не сможете послать данные за кого-то другого.
+ `GET`метод является неизменяемым, тогда как `POST` — изменяемый.

[к оглавлению](#servlets-jsp-jstl)

## В чем разница между `PrintWriter` и `ServletOutputStream`?
`PrintWriter` — класс для работы с символьным потоком, экземпляр которого можно получить через метод `ServletResponse` `getWriter()`;

`ServletOutputStream` — класс для работы байтовым потоком. Для получения его экземпляра используется метод `ServletResponse` `getOutputStream()`.

[к оглавлению](#servlets-jsp-jstl)

## Можно ли одновременно использовать в сервлете `PrintWriter` и `ServletOutputStream`?
Так сделать не получится, т.к. при попытке одновременного вызова `getWriter()` и `getOutputStream()` будет выброшено исключение `java.lang.IllegalStateException` с сообщением, что уже был вызван другой метод.

[к оглавлению](#servlets-jsp-jstl)

## Расскажите об интерфейсе `SingleThreadModel`.
Интерфейс `SingleThreadModel` является маркерным - в нем не объявлен ни один метод, однако, если сервлет реализует этот интерфейс, то метод `service()` этого сервлета гарантированно не будет одновременно выполняться в двух потоках. Контейнер сервлетов либо синхронизирует обращения к единственному экземпляру, либо обеспечивает поддержку пула экземпляров и перенаправление запроса свободному сервлету.
Другими словами, контейнер гарантирует отсутствие конфликтов при одновременном обращении к переменным или методам экземпляра сервлета. Однако существуют также и другие разделяемые ресурсы, которые даже при использовании этого интерфейса, остаются всё так же доступны обработчикам запросов в других потоках. Т.о. пользы от использования этого интерфейса немного и в спецификации Servlet 2.4 он был объявлен `deprecated`.

[к оглавлению](#servlets-jsp-jstl)

## Что означает _URL encoding_? Как это осуществить в Java?
__URL Encoding__ — процесс преобразования данных в форму CGI (Common Gateway Interface), не содержащую пробелов и нестандартных символов, которые заменяются в процессе кодирования на специальные escape-символы. В Java для кодирования строки используется метод `java.net.URLEncoder.encode(String str, String unicode)`. Обратная операция декодирования возможна через использование метода `java.net.URLDecoder.decode(String str, String unicode)`. 

> `Hello мир!` преобразовывается в `Hello%20%D0%BC%D0%B8%D1%80!`.

[к оглавлению](#servlets-jsp-jstl)

## Какие различные методы управления сессией в сервлетах вы знаете?
При посещении клиентом Web-ресурса и выполнении вариантов запросов, контекстная информация о клиенте не хранится. В протоколе HTTP нет возможностей для сохранения и изменения информации о предыдущих посещениях клиента. Сеанс (сессия) – соединение между клиентом и сервером, устанавливаемое на определенное время, за которое клиент может отправить на сервер сколько угодно запросов. Сеанс устанавливается непосредственно между клиентом и Web-сервером. Каждый клиент устанавливает с сервером свой собственный сеанс. Сеансы используются для обеспечения хранения данных во время нескольких запросов Web-страницы или на обработку информации, введенной в пользовательскую форму в результате нескольких HTTP-соединений (например, клиент совершает несколько покупок в интернет-магазине; студент отвечает на несколько тестов в системе дистанционного обучения).

Существует несколько способов обеспечения уникального идентификатора сессии:

+ __User Authentication__ – Предоставление учетных данных самим пользователем в момент аутентификации. Переданная таким образом информация в дальнейшем используется для поддержания сеанса. Это метод не будет работать, если пользователь вошёл в систему одновременно из нескольких мест.
+ __HTML Hidden Field__ – Присвоение уникального значения скрытому полю HTML страницы, в момент когда пользователь начинает сеанс. Этот метод не может быть использован со ссылками, потому что нуждается в подтверждении формы со скрытым полем каждый раз во время формирования запроса. Кроме того, это не безопасно, т.к. существует возможность простой подмены такого идентификатора.
+ __URL Rewriting__ – Добавление идентификатора сеанса как параметра URL. Достаточно утомительная операция, потому что требует постоянного отслеживания этого идентификатора при каждом запросе или ответе.
+ __Cookies__ – Использование небольших фрагментов данных, отправленных web-сервером и хранимых на устройстве пользователя. Данный метод не будет работать, если клиент отключает использование cookies.
+ __Session Management API__ – Использование специального API для отслеживания сеанса, построенный на основе и на методах описанных выше и который решает частные проблемы перечисленных способов:
    + Чаще всего недостаточно просто отслеживать сессию, необходимо ещё и сохранять какие-либо дополнительные данные о ней, которые могут потребоваться при обработке последующих запросов. Осуществление такого поведения требует много дополнительных усилий.
    + Все вышеперечисленные методы не являются универсальными: для каждого из них можно подобрать конкретный сценарий, при котором они не будут работать.

[к оглавлению](#servlets-jsp-jstl)

## Что такое _cookies_?
__Сookies («куки»)__ — небольшой фрагмент данных, отправленный web-сервером и хранимый на устройстве пользователя. Всякий раз при попытке открыть страницу сайта, web-клиент пересылает соответствующие этому сайту cookies web-серверу в составе HTTP-запроса. Применяется для сохранения данных на стороне пользователя и на практике обычно используется для:

+ аутентификации пользователя;
+ хранения персональных предпочтений и настроек пользователя;
+ отслеживания состояния сеанса доступа пользователя;
+ ведения разнообразной статистики.

[к оглавлению](#servlets-jsp-jstl)

## Какие методы для работы с cookies предусмотрены в сервлетах?
Servlet API предоставляет поддержку cookies через класс `javax.servlet.http.Cookie`:

+ Для получения массива cookies из запроса необходимо воспользоваться методом `HttpServletRequest.getCookies()`. Методов для добавления cookies в `HttpServletRequest` не предусмотрено.
+ Для добавления cookie в ответ используется `HttpServletResponse.addCookie(Cookie c)`. Метода получения cookies в `HttpServletResponse` отсутствует.

[к оглавлению](#servlets-jsp-jstl)

## Что такое _URL Rewriting_?
__URL Rewriting__ - специальная перезапись (перекодирование) оригинального URL. Данный механизм может использоваться для управления сессией в сервлетах, когда _cookies_ отключены.

[к оглавлению](#servlets-jsp-jstl)

## Зачем нужны и чем отличаются методы `encodeURL()` и `encodeRedirectURL()`?
`HttpServletResponse.encodeURL()` предоставляет способ преобразования URL в HTML гиперссылку с преобразованием спецсимволов и пробелов, а так же добавления _session id_ к URL. Такое поведение аналогично `java.net.URLEncoder.encode()`, но с добавлением дополнительного параметра `jsessionid` в конец URL.

Метод `HttpServletResponse.encodeRedirectURL()` преобразует URL для последующего использования в методе `sendRedirect()`. 

Таким образом для HTML гиперссылок при _URL rewriting_ необходимо использовать `encodeURL()`, а для URL при перенаправлении - `encodeRedirectUrl()`.

[к оглавлению](#servlets-jsp-jstl)

## Что такое _«сессия»_?
__Сессия__  - это сеанс связи между клиентом и сервером, устанавливаемый на определенное время. Сеанс устанавливается непосредственно между клиентом и веб-сервером в момент получения первого запроса к веб-приложению. Каждый клиент устанавливает с сервером свой собственный сеанс, который сохраняется до окончания работы с приложением.

[к оглавлению](#servlets-jsp-jstl)

## Как уведомить объект в сессии, что сессия недействительна или закончилась?
Чтобы быть уверенным в том, что объект будет оповещён о прекращении сессии, нужно реализовать интерфейс `javax.servlet.http.HttpSessionBindingListener`. Два метода этого интерфейса: `valueBound()` и `valueUnbound()` используются при добавлении объекта в качестве атрибута к сессии и при уничтожении сессии соответственно.

[к оглавлению](#servlets-jsp-jstl)

## Какой существует эффективный способ удостоверится, что все сервлеты доступны только для пользователя с верной сессией?
Сервлет фильтры используются для перехвата всех запросов между контейнером сервлетов и сервлетом. Поэтому логично использовать соответствующий фильтр для проверки необходимой информации (например валидности сессии) в запросе.

[к оглавлению](#servlets-jsp-jstl)

## Как мы можем обеспечить _transport layer security_ для нашего веб приложения?
Для обеспечения _transport layer security_ необходимо настроить поддержку SSL сервлет контейнера. Как это сделать зависит от конкретной реализации сервлет-контейнера.

[к оглавлению](#servlets-jsp-jstl)

## Как организовать подключение к базе данных, обеспечить журналирование в сервлете?
При работе с большим количеством подключений к базе данных рекомендуется инициализировать их в _servlet context listener_, а также установить в качестве атрибута контекста для возможности использования другими сервлетами. 

Журналирование подключается к сервлету стандартным для логгера способом (например для _log4j_ это может быть property-файл или XML-конфигурация) , а далее эта информация используется при настройке соответствующего _context listener_.

[к оглавлению](#servlets-jsp-jstl)

## Какие основные особенности появились в спецификации _Servlet 3_?
+ __Servlet Annotations__. До Servlet 3 вся конфигурация содержалась в `web.xml`, что приводило к ошибкам и неудобству при работе с большим количестве сервлетов. Примеры аннотаций: `@WebServlet`, `@WebInitParam`, `@WebFilter`, `@WebListener`.
+ __Web Fragments__. Одностраничное веб приложение может содержать множество модулей: все модули прописываются в `fragment.xml` в папке `META-INF\`. Это позволяет разделять веб приложение на отдельные модули, собранные как .jar-файлы в отдельной `lib\` директории.
+ __Динамическое добавление веб компонентов__. Появилась возможность программно добавлять фильтры и слушатели, используя `ServletContext` объект. Для этого применяются методы `addServlet()`, `addFilter()`, `addListener()`. Используя это нововведение стало доступным построение динамической системы, в которой необходимый объект будет создан и вызван только по необходимости.
+ __Асинхронное выполнение__. Поддержка асинхронной обработки позволяет передать выполнение запроса в другой поток без удержания всего сервера занятым.

[к оглавлению](#servlets-jsp-jstl)

## Какие способы аутентификации доступны сервлету?
Спецификация сервлетов определяет четыре типа проверки подлинности:

+ __HTTP Basic Authentication__ - `BASIC`. При доступе к закрытым ресурсам появится окно, которое попросит ввести данные для аутентификации.
+ __Form Based Login__ - `FORM`. Используется собственная html форма:
+ __HTTP Digest Authentication__ - `DIGEST`. Цифровая аутентификация с шифрованием.
+ __HTTPS Authentication__ - `CLIENT-CERT`. Аутентификация с помощью клиентского сертификата.

```xml
<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.html</form-login-page>
        <form-error-page>/error.html</form-error-page>
    </form-login-config>
</login-config>
```

[к оглавлению](#servlets-jsp-jstl)

## Что такое _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.

[к оглавлению](#servlets-jsp-jstl)

## Зачем нужен JSP?
JSP расширяет технологию сервлетов обеспечивая возможность создания динамических страницы с HTML подобным синтаксисом.

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

Еще одним преимуществом JSP является горячее развертывание - возможность заменить одну страницу на другую непосредственно в контейнере без необходимости перекомпилировать весь проект или перезапускать сервер.

Однако рекомендуется избегать написания серьёзной бизнес-логики в JSP и использовать страницу только в качестве представления.

[к оглавлению](#servlets-jsp-jstl)

## Опишите, как обрабатываются JSP страницы, начиная от запроса к серверу, заканчивая ответом пользователю.
Когда пользователь переходит по ссылке на страницу `page.jsp`, он отправляет http-запрос на сервер `GET /page.jsp`. Затем, на основе этого запроса и текста самой страницы, сервер генерирует java-класс, компилирует его и выполняет полученный сервлет, формирующий ответ пользователю в виде представления этой страницы, который сервер и перенаправляет обратно пользователю.

[к оглавлению](#servlets-jsp-jstl)

## Расскажите об этапах (фазах) жизненного цикла JSP.
Если посмотреть код внутри созданной JSP страницы, то он будет выглядеть как HTML и не будет похож на java класс. Конвертацией JSP страниц в HTML код занимается контейнер, который так же создает и сервлет для использования в веб приложении. 

Жизненный цикл JSP состоит из нескольких фаз, которыми руководит JSP контейнер:

+ __Translation__ – проверка и парсинг кода JSP страницы для создания кода сервлета. 
+ __Compilation__ – компиляция исходного кода сервлета.
+ __Class Loading__ – загрузка скомпилированного класса в память.
+ __Instantiation__ – внедрение конструктора без параметра загруженного класса для инициализации в памяти.
+ __Initialization__ – вызов `init()` метода объекта JSP класса и инициализация конфигурации сервлета с первоначальными параметрами, которые указаны в дескрипторе развертывания (`web.xml`). После этой фазы JSP способен обрабатывать запросы клиентов. Обычно эти фазы происходят после первого запроса клиента (т.е. ленивая загрузка), но можно настроить загрузку и инициализацию JSP на старте приложения по аналогии с сервлетами.
+ __Request Processing__ – длительный жизненный цикл обработки запросов клиента JSP страницей. Обработка является многопоточной и аналогична сервлетам — для каждого запроса создается новый поток, объекты `ServletRequest` и `ServletResponse`, происходит выполнение сервис методов.
+ __Destroy__ – последняя фаза жизненного цикла JSP, на которой её класс удаляется из памяти. Обычно это происходит при выключении сервера или выгрузке приложения.

[к оглавлению](#servlets-jsp-jstl)

## Расскажите о методах жизненного цикла JSP.
Контейнер сервлетов (например, Tomcat, GlassFish) создает из JSP-страницы класс сервлета, наследующего свойства интерфейса `javax.servlet.jsp.HttpJspBase` и включающего следующие методы:

+ `jspInit()` — метод объявлен в JSP странице и реализуется с помощью контейнера. Этот метод вызывается один раз в жизненном цикле JSP для того, чтобы инициализировать конфигурационные параметры указанные в дескрипторе развертывания. Этот метод можно переопределить с помощью определения элемента _JSP scripting_ и указания необходимых параметров для инициализации;
+ `_jspService()` — метод переопределяется контейнером автоматически и соответствует непосредственно коду JSP, описанному на странице. Этот метод определен в интерфейсе `HttpJspPage`, его имя начинается с нижнего подчеркивания и он отличается от других методов жизненного цикла тем, что его невозможно переопределить;
+ `jspDestroy()` — метод вызывается контейнером для удаления объекта из памяти (на последней фазе жизненного цикла JSP - Destroy). Метод вызывается только один раз и доступен для переопределения, предоставляя возможность освободить ресурсы, которые были созданы в `jspInit()`.

[к оглавлению](#servlets-jsp-jstl)

## Какие методы жизненного цикла JSP могут быть переопределены?
Возможно переопределить лишь `jspInit()` и `jspDestroy()` методы.

[к оглавлению](#servlets-jsp-jstl)

## Как можно предотвратить прямой доступ к JSP странице из браузера?
Прямой доступ к директории `/WEB-INF/` из веб-приложения отсутствует. Поэтому JSP-страницы можно расположить внутри этой папки и тем самым запретить доступ к странице из браузера. Однако, по аналогии с описанием сервлетов, будет необходимо настроить дескриптор развертывания:

```xml
<servlet>
    <servlet-name>Example</servlet-name>
    <jsp-file>/WEB-INF/example.jsp</jsp-file>
    <init-param>
        <param-name>exampleParameter</param-name>
        <param-value>parameterValue</param-value>
    </init-param>
</servlet>
    
<servlet-mapping>
    <servlet-name>Example</servlet-name>
    <url-pattern>/example.jsp</url-pattern>
</servlet-mapping>
```

[к оглавлению](#servlets-jsp-jstl)

## Какая разница между _динамическим_ и _статическим_ содержимым JSP?
Статическое содержимое JSP (HTML, код JavaScript, изображения и т.д.) не изменяется в процессе работы веб приложения. 

Динамические ресурсы созданы для того, чтобы отображать свое содержимое в зависимости от пользовательских действий. Обычно они представлены в виде выражений EL (Expression Language), библиотек JSP-тегов и пр.

[к оглавлению](#servlets-jsp-jstl)

## Как закомментировать код в JSP?
+ `<!—- HTML комментарий; отображается на странице JSP —->` такие комментарии будут видны клиенту при просмотре кода страницы.
+ `<%—- JSP комментарий; не отображается на странице JSP —-%>` такие комментарии описываются в созданном сервлете и не посылаются клиенту. Для любых комментариев по коду или отладочной информации необходимо использовать именно такой тип комментариев.

[к оглавлению](#servlets-jsp-jstl)

## Какие существуют основные типы тегов JSP?
+ _Выражение JSP_: `<%= expression %>` - выражение, которое будет обработано с перенаправлением результата на вывод;
+ _Скриплет JSP_: `<% code %>` - код, добавляемый в метод `service()`.
+ _Объявление JSP_: `<%! code %>` - код, добавляемый в тело класса сервлета вне метода `service()`.
+ _Директива JSP page_: `<%@ page att="value" %>` - директивы для контейнера сервлетов с информацией о параметрах.
+ _Директива JSP include_: `<%@ include file="url" %>` - файл в локальной системе, подключаемый при трансляции JSP в сервлет.
+ _Комментарий JSP_: `<%-- comment --%>` - комментарий; игнорируется при трансляции JSP страницы в сервлет.

[к оглавлению](#servlets-jsp-jstl)

## Что вы знаете о действиях JSP (_Action tag_ и _JSP Action Elements_).
__Action tag__ и __JSP Action Elements__ предоставляют методы работы с Java Beans, подключения ресурсов, проброса запросов и создания динамических XML элементов. Такие элементы всегда начинаются с записи `jsp:` и используются непосредственно внутри страницы JSP без необходимости подключения сторонних библиотек или дополнительных настроек.

Наиболее часто используемыми JSP Action Elements являются:

+ `jsp:include`: `<jsp:include page="относительный URL" flush="true"/>` - подключить файл при запросе страницы. Если необходимо, чтобы файл подключался в процессе трансляции страницы, то используется директива `page` совместно с атрибутом `include`;
+ `jsp:useBean`: `<jsp:useBean att=значение*/>` или `<jsp:useBean att=значение*>...</jsp:useBean>` - найти или создать Java bean;
+ `jsp:setProperty`: `<jsp:setProperty att=значение*/>` - установить свойства Java bean, или явно, или указанием на соответствующее значение, передаваемое при запросе;
+ `jsp:forward`: `<jsp:forward page="относительный URL"/>` - передать запрос другой странице;
+ `jsp:plugin`: `<jsp:plugin attribute="значение"*>...</jsp:plugin>` - сгенерировать (в зависимости от типа браузера) тэги `OBJECT` или `EMBED` для апплета, использующего технологию Java Plugin.

[к оглавлению](#servlets-jsp-jstl)

## Взаимодействие _JSP - сервлет - JSP_.
_«JSP - сервлет - JSP»_ архитектура построения приложений носит название _MVC (Model/View/Controller)_:

+ _Model_ - классы данных и бизнес-логики;

+ _View_ - страницы JSP;

+ _Controller_ - сервлеты.

[к оглавлению](#servlets-jsp-jstl)

## Какие области видимости переменных существуют в JSP?
Область видимости объектов определяется тем контекстом в который помещается данный объект. В зависимости от той или иной области действия так же определяется время существования объекта. 

В JSP предусмотрены следующие области действия переменных (объектов):

+ `request` область действия запроса - объект будет доступен на текущей JSP странице, странице пересылки (при использовании `jsp:forward`) или на включаемой странице (при использовании `jsp:include`);
+ `session` область действия сессии - объект будет помещен в сеанс пользователя, будет доступен на всех JSP страницах и будет существовать пока существует сессия пользователя, или он не будет из нее принудительно удален.
+ `application` область действия приложения - объект будет доступен для всех пользователей на всех JSP страницах и будет существовать на протяжении всей работы приложения или пока не будет удален принудительно и контекста приложения.
+ `page` область действия страницы - объект будет доступен только на той странице, где он определен. На включаемых (`jsp:include`) и переадресуемых (`jsp:forward`) страницах данный объект уже не будет доступен.

Таким образом, чтобы объект был доступен всем JSP страницам, необходимо указать область видимости `application` или `session`, в зависимости от того требуется ли доступ к объекту всем пользователям или только текущему.

Для указания требуемой области действия при определении объекта на JSP странице используется атрибут scope тега `jsp:useBean`:

```
<jsp:useBean id="myBean" class="ru.javacore.MyBean" scope="session"/>
```

Если не указывать атрибут `scope`, то по умолчанию задается область видимости страницы `page`

[к оглавлению](#servlets-jsp-jstl)

## Какие неявные, внутренние объекты и методы есть на JSP странице?
__JSP implicit objects (неявные объекты)__ создаются контейнером при конвертации JSP страницы в код сервлета для помощи разработчикам. Эти объекты можно использовать напрямую в скриптлетах для передачи информации в сервис методы, однако мы не можем использовать неявные объекты в JSP Declaration, т.к. такой код пойдет на уровень класса.

Существует 9 видов неявных объектов, которые можно использовать прямо на JSP странице. Семь из них объявлены как локальные переменные в начале `_jspService()` метода, а два оставшихся могут быть использованы как аргументы метода `_jspService()`.

+ `out Object` : 

```
<strong>Current Time is</strong>: <% out.print(new Date()); %><br>
```

+ `request Object` : 

```
<strong>Request User-Agent</strong>: <%=request.getHeader("User-Agent") %><br>
```

+ `response Object` : 

```
<strong>Response</strong>: <%response.addCookie(new Cookie("Test","Value")); %>
```

+ `config Object` : 

```
<strong>User init param value</strong>: <%=config.getInitParameter("User") %><br>
```

+ `application Object` : 

```
<strong>User context param value</strong>: <%=application.getInitParameter("User") %><br>
``` 

+ `session Object` : 

```
<strong>User Session ID</strong>: <%=session.getId() %><br>
```

+ `pageContext Object` :

```
<% pageContext.setAttribute("Test", "Test Value"); %> 
<strong>PageContext attribute</strong>: {Name="Test",Value="<%=pageContext.getAttribute("Test") %>"}<br>
```

+ `page Object` : 

```
<strong>Generated Servlet Name</strong>: <%=page.getClass().getName() %>
```

+ `exception Object` : 

``` 
<strong>Exception occured</strong>: <%=exception %><br>
```

[к оглавлению](#servlets-jsp-jstl)

## Какие неявные объекты не доступны в обычной JSP странице?
Неявный объект исключений JSP недоступен в обычных JSP страницах и используется на страницах ошибок JSP (_errorpage_) только для того, чтобы перехватить исключение, выброшенное JSP страницей и далее предоставить какую-либо полезную информацию клиенту.

[к оглавлению](#servlets-jsp-jstl)

## Что вы знаете о `PageContext` и какие преимущества его использования?
Неявный объект JSP - экземпляр класса `javax.servlet.jsp.PageContext` предоставляет доступ ко всем пространствам имён, ассоциированным с JSP-страницей, а также к различным её атрибутам.
Остальные неявные объекты добавляются к `pageContext` автоматически.

Класс `PageContext` это абстрактный класс, а его экземпляр можно получить через вызов метода `JspFactory.getPageContext()`, и освободить через вызов метода `JspFactory.releasePageContext()`.

`PageContext` обладает следующим набором особенностей и возможностей:

+ единый API для обслуживания пространств имён различных областей видимости;
+ несколько удобных API для доступа к различным `public`-объектам;
+ механизм получения `JspWriter` для вывода;
+ механизм обслуживания использования сессии страницей;
+ механизм экспонирования («показа») атрибутов директивы `page` среде скриптинга;
+ механизмы направления или включения текущего запроса в другие компоненты приложения;
+ механизм обработки процессов исключений на страницах ошибок _errorpage_;

[к оглавлению](#servlets-jsp-jstl)

## Как сконфигурировать параметры инициализации для JSP?
Параметры инициализации для JSP задаются в `web.xml` файле аналогично сервлетам - элементами `servlet` и `servlet-mapping`. Единственным отличием будет указание местонахождения JSP страницы:

```xml
<servlet>
    <servlet-name>Example</servlet-name>
    <jsp-file>/WEB-INF/example.jsp</jsp-file>
    <init-param>
        <param-name>exampleParameter</param-name>
        <param-value>parameterValue</param-value>
    </init-param>
</servlet>
```

[к оглавлению](#servlets-jsp-jstl)

## Почему не рекомендуется использовать скриплеты (скриптовые элементы) в JSP?
JSP страницы используются в основном  для целей отображения представления (_view_), а вся бизнес-логика (_controller_) и модель (_model_) должны быть реализованы в сервлетах или классах-моделях. Обязанность JSP страницы - создание HTML ответа из переданных через атрибуты параметров. Большая часть JSP содержит HTML код а для того, чтобы помочь верстальщикам понять JSP код страницы предоставляется функционал элементов _action_, _JSP EL_, _JSP Standart Tag Library_. Именно их и необходимо использовать вместо скриптлетов для создания моста между (JSP)HTML и (JSP)Java частями.

[к оглавлению](#servlets-jsp-jstl)

## Можно ли определить класс внутри JSP страницы?
Определить класс внутри JSP страницы можно, но это считается плохой практикой:

```java
<%!
private static class ExampleOne {
  //...
}
%>

<%
private class ExampleTwo {
  //...
}
%>
```

[к оглавлению](#servlets-jsp-jstl)

## Что вы знаете о Языке выражений JSP (JSP Expression Language – EL)?
__JSP Expression Language (EL)__ — скриптовый язык выражений, который позволяет получить доступ к Java компонентам (JavaBeans) из JSP. Начиная с JSP 2.0 используется внутри JSP тегов для отделения Java кода от JSP для обеспечения лёгкого доступа к Java компонентам, уменьшая при этом количество кода Java в JSP-страницах, или даже полностью исключая его.

Развитие EL происходило с целью сделать его более простым для дизайнеров, которые имеют минимальные познания в языке программирования Java. До появления языка выражений, JSP имел несколько специальных тегов таких как скриптлеты (англ.), выражения и т. п. которые позволяли записывать Java код непосредственно на странице. С использованием языка выражений веб-дизайнер должен знать только то, как организовать вызов соответствующих java-методов.

Язык выражений JSP 2.0 включает:

+ Создание и изменение переменных.
+ Управление потоком выполнения программы: ветвление, выполнение различных типов итераций и т.д.
+ Упрощенное обращение к встроенным JSP-объектам.
+ Возможность создавать собственные функции.

Язык выражений используется внутри конструкции `${ ... }`. Подобная конструкция может размещаться либо отдельно, либо в правой части выражения установки атрибута тега.

[к оглавлению](#servlets-jsp-jstl)

## Какие типы EL операторов вы знаете?
Операторы в EL поддерживают наиболее часто используемые манипуляции данными.

Типы операторов:

+ Стандартные операторы отношения: `==` (или `eq`), `!=` (или `neq`), `<` (или `lt`), `>` (или `gt`), `<=` (или `le`), `>=` (или `ge`).
+ Арифметические операторы: `+`, `–`, `*`, `/` (или `div`), `%` (или `mod`).
+ Логические операторы: `&&` (или `and`), `||` (или `or`), `!` (или `not`).
+ Оператор `empty` – используется для проверки переменной на `null`, или «пустое значение», который зависит от типа проверяемого объекта. Например, нулевая длина для строки или нулевой размер для коллекции.

[к оглавлению](#servlets-jsp-jstl)

## Назовите неявные, внутренние объекты JSP EL и их отличия от объектов JSP.
Язык выражений JSP предоставляет множество неявных объектов, которые можно использовать для получения атрибутов в различных областях видимости (scopes) и для значений параметров. Важно отметить, что они отличаются от неявных объектов JSP и содержат атрибуты в заданной области видимости. Наиболее часто использующийся implicit object в JSP EL и JSP page — это объект pageContext. Ниже представлена таблица неявных объектов JSP EL.

[к оглавлению](#servlets-jsp-jstl)

## Как отключить возможность использования EL в JSP?
Для игнорирования выполнения языка выражений на странице существует два способа:

+ использовать директиву `<%@ page isELIgnored = «true» %>`,
+ настроить `web.xml` (лучше подходит для отключения EL сразу на нескольких страницах):

```xml
<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <el-ignored>true</el-ignored>
    </jsp-property-group>
</jsp-config>
```

[к оглавлению](#servlets-jsp-jstl)

## Как узнать тип HTTP метода используя JSP EL?
`${pageContext.request.method}`.

[к оглавлению](#servlets-jsp-jstl)

## Что такое _JSTL (JSP Standard tag library)_?
__JavaServer Pages Standard Tag Library, JSTL, Стандартная библиотека тегов JSP__ — расширение спецификации JSP (конечный результат _JSR 52_), добавляющее библиотеку JSP тегов для общих нужд, таких как разбор XML данных, условная обработка, создание циклов и поддержка интернационализации.

JSTL является альтернативой такому виду встроенной в JSP логики, как _скриплеты_ (прямые вставки Java кода). Использование стандартизованного множества тегов предпочтительнее, поскольку получаемый код легче поддерживать и проще отделять бизнес-логику от логики отображения.

Для использования JSTL тегов необходимо:

+ подключить зависимости, например в `pom.xml`:

```xml
<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>
```

+ указать пространство имен основных тегов JSTL через указание на JSP странице код:

```
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
```

[к оглавлению](#servlets-jsp-jstl)

## Из каких групп тегов состоит библиотека _JSTL_?
Группы тегов JSTL согласно их функциональности:

+ _Core Tags_ предоставляют возможности итерации, обработки исключений, URL, _forward_, _redirect response_ и т.д.
+ _Formatting Tags_ и _Localization Tags_ предоставляют возможности по форматированию чисел, дат и поддержки _i18n_ локализации и _resource bundles_.
+ _SQL Tags_ – поддержка работы с базами данных.
+ _XML Tags_ используются для работы с XML документами: парсинга, преобразования данных, выполнения выражений _XPath_ и т.д..
+ _JSTL Functions Tags_ предоставляет набор функций, которые позволяют выполнять различные операции со строками и т.п. Например, по конкатенации или разбиению строк.

[к оглавлению](#servlets-jsp-jstl)

## Какая разница между `<c:set>` и `<jsp:useBean>`?
Оба тега создают и помещают экземпляры в заданную область видимости, но `<jsp:useBean>` только создаёт экземпляр конкретного типа, а `<c:set>`, создав экземпляр, позволяет дополнительно извлекать значение, например, из параметров запроса, сессии и т. д. 

[к оглавлению](#servlets-jsp-jstl)

## Чем отличается `<c:import>` от `<jsp:include>` и директивы `<%@include %>`?
По сравнению с action-тегом `<jsp:include>` и директивой `<%@include %>` тег `<c:import>` обеспечивает более совершенное включение динамических ресурсов, т.к. получает доступ к источнику, чтение информации из которого происходит непосредственно без буферизации и контент включается в исходную JSP построчно.

[к оглавлению](#servlets-jsp-jstl)

## Как можно расширить функциональность JSP?
## Что вы знаете о написании пользовательских JSP тегов?
## Приведите пример использования собственных тегов.
JSP можно расширить с помощью создания собственных тегов с необходимой функциональностью, которые можно добавить в библиотеку тегов на страницу JSP указав необходимое пространство имен. 

> /WEB-INF/exampleTag.tld

```xml
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_1.xsd">
    <tlib-version>1.0</tlib-version>
    <short-name>example</short-name>
    <uri>/WEB-INF/exampleTag</uri>
    <tag>
        <name>exampleTag</name>
        <tag-class>xyz.company.ExampleTag</tag-class>
        <body-content>empty</body-content>
        <info>The example tag displays Hello World!</info>
    </tag>
</taglib>
```

> xyz.company.ExampleServlet.java

```java
package xyz.company;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class ExampleTag extends TagSupport{
    private static final long serialVersionUID = 1L;

    @Override
    public int doStartTag() throws JspException {
        try {
            pageContext.getOut().print("Hello World!");
        } catch(IOException ioException) {
            throw new JspException("Error: " + ioException.getMessage());
        }       
        return SKIP_BODY;
    }
}
```

> exampleTag.jsp

```
<%@ taglib uri="/WEB-INF/exampleTag.tld" prefix="example"%>
<%@ page session="false" pageEncoding="UTF-8"%>
<html>
<head>
<title>Example Tag</title>
</head>
<body>
    <h1>Example Tag</h1>
    <p><example:exampleTage /><p>
</body>
</html>
```

Также в пользовательских тегах существует возможность задать входные параметры. Например, существует необходимость отформатировать каким-либо стилем очень длинное число. Для этого можно использовать собственный тег по типу:

`<mytags:formatNumber number="123456.789" format="#,## #.00"/>`

Используя входные параметры, число должно быть преобразовано на JSP странице в таком виде `123,456.79` согласно шаблону. Т.к. JSTL не предоставляет такой функциональности, необходимо создать пользовательский тег для получения необходимого результата.

[к оглавлению](#servlets-jsp-jstl)

## Как сделать перенос строки в HTML средствами JSP?
Для переноса строки можно использовать тег `c:out` и атрибут `escapeXml`, который отключает обработку HTML элементов. В этом случае браузер получит следующий код в виде строки и обработает элемент `<br>` как требуется:

`<c:out value="<br> creates a new line in HTML" escapeXml="true"></c:out>`

[к оглавлению](#servlets-jsp-jstl)

## Почему не нужно конфигурировать стандартные JSP теги в `web.xml`?
Стандартные теги JSP не конфигурируются в `web.xml`, потому что tld файлы уже находятся внутри каталога `/META-INF/` в jar файлах JSTL. 

Когда контейнер загружает веб-приложение и находит tld файлы в в jar файле в директории `/META-INF/`, то он автоматически настраивает их для непосредственного использования на JSP страницах. Остается только задать пространство имен на JSP странице.

[к оглавлению](#servlets-jsp-jstl)

## Как можно обработать ошибки JSP страниц?
Для обработки исключений выброшенных на JSP странице достаточно лишь задать страницу ошибки JSP и при её создании установить значение _page directive attribute_ `isErrorPage` в значение `true`. Таким образом будет предоставлен доступ к неявным объектам исключений в JSP и появится возможность передавать собственные, более информативные сообщения об ошибках клиенту. При этом настройка дескриптора развертывания выглядит так:

```xml
<error-page>
     <error-code>404</error-code>
     <location>/error.jsp</location>
</error-page>
  
<error-page>
     <exception-type>java.lang.Throwable</exception-type>
     <location>/error.jsp</location>
</error-page>
```

[к оглавлению](#servlets-jsp-jstl)

## Как происходит обработка ошибок с помощью JSTL?
Для перехвата и обработки исключений в служебных методах класса служат JSTL Core Tags `c:catch` и `c:if`. 

> Тег `c:catch` перехватывает исключение и обертывает его в переменную `exception`, доступную для обработки в теге `c:if`:
```
<c:catch var ="exception">
   <% int x = 42/0;%>
</c:catch>  
<c:if test = "${exception ne null}">
   <p>Exception is : ${exception} <br />
   Exception Message: ${exception.message}</p>
</c:if>
```

Обратите внимание что используется язык выражений JSP EL в теге `c:if`.

[к оглавлению](#servlets-jsp-jstl)

## Как конфигурируется JSP в дескрипторе развертывания.
Для настройки различных параметров JSP страниц используется элемент `jsp-config`, который отвечает за:

+ управление элементами скриптлетов на странице;
+ управления выполнением в языке выражений;
+ определение шаблона URL для encoding;
+ определение размера буфера, который используется для объектов на странице;
+ обозначение групп ресурсов, соответствующих шаблону URL, которые должны быть обработаны как XML документ.

```xml
<jsp-config>
    <taglib>
        <taglib-uri>http://company.xyz/jsp/tlds/customtags</taglib-uri>
        <taglib-location>/WEB-INF/exampleTag.tld</taglib-location>
    </taglib>
</jsp-config>
```

[к оглавлению](#servlets-jsp-jstl)

## Можно ли использовать Javascript на JSP странице?
Да, это возможно. Несмотря на то, что JSP это серверная технология, на выходе она всё равно создает `HTML` страницу, на которую можно добавлять Javascript и CSS.

[к оглавлению](#servlets-jsp-jstl)

## Всегда ли создается объект сессии на JSP странице, можно ли отключить его создание?
Jsp-страница, по умолчанию, всегда создает сессию. Используя директиву `page` с атрибутом `session` можно изменить это поведение:

`<%@ page session ="false" %>`

[к оглавлению](#servlets-jsp-jstl)

## Какая разница между `JSPWriter` и сервлетным `PrintWriter`?
`PrintWriter` является объектом отвечающим за запись содержания ответа на запрос. `JspWriter` использует объект `PrintWriter` для буферизации. Когда буфер заполняется или сбрасывается, `JspWriter` использует объект `PrintWriter` для записи содержания в ответ.

[к оглавлению](#servlets-jsp-jstl)

## Опишите общие практические принципы работы с JSP.
Хорошей практикой работы с технологией JSP является соблюдение следующих правил:

+ Следует избегать использования элементов скриптлетов на странице. Если элементы _action_, _JSTL_, _JSP EL_ не удовлетворяют потребностям, то желательно написать собственный тег.
+ Рекомендуется использовать разные виды комментариев: так JSP комментарии необходимы для уровня кода и отладки, т.к. они не будут показаны клиенту.
+ Не стоит размещать какой-либо бизнес логики внутри JSP страницы. Страницы должны использоваться только для создания ответов клиенту.
+ Для повышения производительности лучше отключать создание сессии на странице, когда это не требуется.
+ Директивы `taglib`, `page` в начале JSP страницы улучшают читабельность кода.
+ Следует правильно использовать директиву `include` и элемент `jsp:include action`. Первая используется для статических ресурсов, а второй для динамических ресурсов времени выполнения.
+ Обработку исключений нужно производить с помощью страниц ошибок. Это помогает избегать запуска специальных служебных методов и может повысить производительность.
+ Использующиеся CSS и JavaScript должны быть разнесены в разные файлы и подключаться в начале страницы.
+ В большинстве случаев JSTL должно хватать для всех нужд. Если это не так, то в начале следует проанализировать логику своего приложения, и попробовать перенести выполнения кода в сервлет, а далее с помощью установки атрибутов использовать на JSP странице только результат.


# Источники
+ [javastudy.ru](http://javastudy.ru/interview/jee-servlet-api-questions/)
+ [java2ee.ru](http://www.java2ee.ru/servlets/)
+ [Java-online](http://java-online.ru/jsp-questions.xhtml)
+ [Codenet](http://www.codenet.ru/webmast/java/jsp.php)
+ [JavaTalks Articles](https://articles.javatalks.ru/articles/24)

[Вопросы для собеседования](README.md)
