HTTP-сессия в мире Java
В любом веб-приложении одним из краеугольных вопросов является поддержка клиентских сессий. Платформа JavaEE не исключение и для этих целей в ней существует специализированный HttpSession API, доступ к которому есть у любого веб-приложения, развёрнутого в некотором сервлет-контейнере. Что же из себя представляют эти самые сессии?
Возможно, вам известно, что протокол HTTP и веб-серверы по природе своей являются stateless, и каждый новый запрос от клиента расценивается сервером как абсолютно новый, ничего не знающий об истории предшествующих обращений. Вы скажете, а как же тогда реализуются интернет-магазины, знающие о списке добавленных в корзину товаров своих покупателей?
А что такое сессия?
Сессия — это диалоговое состояние между клиентом и сервером, включающее информацию о предыдущих запросах клиента и ответах сервера. В силу того, что протокол и сами веб-сервера не обеспечивают сохранение состояния, то единственной возможностью для этого является передача всей необходимой информации о запросе в нём самом.
Чтобы этого не делать, каждый запрос от данного клиента сервер ассоциирует с некоторой уникальной информацией об установленной сессии (идентификатор сессии), пробрасывая её в каждом запросе и ответе. Для передачи данного UID наиболее популярными являются такие способы, как использование пользовательских cookies, скрытые поля формы и передача непосредственно в адресе запроса.
При разработке веб-приложения, конечно, функцию генерации UID и последующей его передачи от клиента к серверу может взять на себя само приложение. Но тогда разработчик будет ответственен за все возможные обращения, каждый раз проверяя, а не забыл ли он передать это значение, при этом генерируя огромное количество boilerplate-кода.
Что же в Java Enterprise?
К великому счастью, разработчики JavaEE освобождены от такой рутины и выполнение данной задачи взвалено на плечи контейнера, в пределах которого развёрнуто приложение. Осталось понять, каким же образом он это делает?
Работа с пользовательскими сессиями веб-приложений в JavaEE вынесена в раздел Servlet API и осуществляется средствами интерфейса
HttpSession request.getSession(boolean create) — для ложного значения параметра create данный метод возвращает объект сессии, если он был создан у данного запроса, и null в противном случае; в случае истинного значения create данный метод равносилен методу п.2.HttpSession request.getSession() — если сеанс не установлен, то контейнер его создаёт, иначе возвращает уже созданный объект сессии.
В момент, когда сеанс установлен, сервлет-контейнер создаёт пользовательский cookie с именем JSESSIONID, значение которого содержит уникальный идентификатор сессии (это же значение можно получить методом String getId() объекта HttpSession). Наряду с этим, в рамках контейнера определяется дефолтное значение таймаута сессии — время неактивного состояния пользователя, приводящее к устареванию его сеанса связи с сервером.
Данное значение конфигурируется на уровне контейнера сервлетов либо непосредственно в веб-приложении на уровне дескриптора развёртывания web.xml или непосредственным вызовом метода
<session-config> <!-- Timeout of inactivity in minutes --> <session-timeout>15</session-timeout> <cookie-config> <http-only>true</http-only> <path>/</path> <!-- Cookie lifetime in seconds --> <max-age>900</max-age> </cookie-config> </session-config>
А что же будет, если пользовательские «печеньки» запрещены на клиентской машине? Данный факт будет выявлен сервером автоматически и для поддержания сеанса будет использован механизм URL Rewriting, который позволяет передавать UID-сессии непосредственно в адресной строке, например так:
http://www.mysite.com/MyApp/myservlet;jsessionid=1E6FEC0D14D044541DD84D2D013D29ED
А зачем они вообще нужны эти http-сессии и какие в принципе возможности они предоставляют — это уже отдельная тема.
Есть вопрос? Напишите в комментариях!