Философия Java

         

Класс Session


Сессия состоит из запроса клиентом одной или нескольких страниц Web сайта за определенный период времени. Например, если вы покупаете бакалею в режиме онлайн, вы хотите, чтобы сессия была подтверждена с того момента, когда вы добавили первый элемент в “свою карзину покупок” до момента проверки состояния карзины. При каждом добавлении в карзину покупок нового элемента в результате получается новое HTTP соединение, котоое не имеет инфрмации о предыдущих соединениях или элементах, уже находящихся в корзине покупок. Чтобы компенсировать утечку информации механики снабдили спецификацией cookie, позволяющей вашему сервлету следить за сессией.

Объект сервлета Session живет на стороне сервера соединительного канала. Он предназначен для сбора полезной информации о клиенте, его перемещении по сайту и взаимодействию с ним. Эти данные могут подходить для представления сессии, так например для элементов в корзине покупок, или это могут быть такие даные, как информация об авторизации, которая была введена при первом входе клиента на ваш Web сайт, и которую не нужно вводить повторно во время выполнения определенных обращений.

Класс Session из API сервлета использует класс Cookie, чтобы сделать эту работу. Однако всем объектам Session необходим уникальный идентификатор некоторого вида, хранимый на стороне клиента и передающийся на сервер. Web сайты могут также использовать другие типы слежения за сессиями, но эти механизмы более сложны для реализации, так как они не инкапсулированы в API сервлетов (так что вы должны писать их руками, чтобы разрешить ситуации, когда клиент отключает cookies).

Вот пример, который реализует слежение за сессиями с помощью сервлетного API:

//: c15:servlets:SessionPeek.java

// Использование класса HttpSession.

import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*;

public class SessionPeek extends HttpServlet { public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Получаем объект Session перед любой


// исходящей посылкой клиенту.

HttpSession session = req.getSession(); res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HEAD><TITLE> SessionPeek "); out.println(" </TITLE></HEAD><BODY>"); out.println("<h1> SessionPeek </h1>"); // Простой счетчик посещений для этой сессии.

Integer ival = (Integer) session.getAttribute("sesspeek.cntr"); if(ival==null) ival = new Integer(1); else ival = new Integer(ival.intValue() + 1); session.setAttribute("sesspeek.cntr", ival); out.println("You have hit this page <b>"

+ ival + "</b> times.<p>"); out.println("<h2>"); out.println("Saved Session Data </h2>"); // Цикл по всем данным сессии:

Enumeration sesNames = session.getAttributeNames(); while(sesNames.hasMoreElements()) { String name = sesNames.nextElement().toString(); Object value = session.getAttribute(name); out.println(name + " = " + value + "<br>"); } out.println("<h3> Session Statistics </h3>"); out.println("Session ID: " + session.getId() + "<br>"); out.println("New Session: " + session.isNew() + "<br>"); out.println("Creation Time: "

+ session.getCreationTime()); out.println("<I>(" + new Date(session.getCreationTime()) + ")</I><br>"); out.println("Last Accessed Time: " + session.getLastAccessedTime()); out.println("<I>(" + new Date(session.getLastAccessedTime()) + ")</I><br>"); out.println("Session Inactive Interval: "

+ session.getMaxInactiveInterval()); out.println("Session ID in Request: "



+ req.getRequestedSessionId() + "<br>"); out.println("Is session id from Cookie: "

+ req.isRequestedSessionIdFromCookie() + "<br>"); out.println("Is session id from URL: "



+ req.isRequestedSessionIdFromURL() + "<br>"); out.println("Is session id valid: "

+ req.isRequestedSessionIdValid() + "<br>"); out.println("</BODY>"); out.close(); } public String getServletInfo() { return "A session tracking servlet"; } } ///:~

Внутри метода service( ), getSession( ) вызывает ся для объекта запроса, который возвращает объект Session, связанный с этим запросом. Объект Session не перемещается по сети, а вместо этого он живет на сервере и ассоциируется с клиентом и его запросами.

getSession( ) существует в двух версиях: без параметров, как использовано здесь, и getSession(boolean). getSession(true) эквивалентно вызову getSession( ). Причина введения boolean состоит определении, когда вы хотите создать объект сессии, если он не найден. getSession(true) вызывается чаще всего, отсюда и взялось getSession( ).

объект Session, если он не новый, детально сообщает нам о клиенте из предыдущих визитов. Если объект Session новый, то программа начинает сбор информации об активности этого клиента в этом визите. Сбор информации об этом клиенте выполняется методами setAttribute( ) и getAttribute( ) объекта сессии.

java.lang.Object getAttribute(java.lang.String) void setAttribute(java.lang.String name, java.lang.Object value)

Объект Session использует простые пары из имени и значения для загрузки информации. Имя является объектом типа String, а значение может быть любым объектом, унаследованным от java.lang.Object. SessionPeek следит за тем, сколько раз клиент возвращался во время сессии. Это сделано с помощью объекта sesspeek.cntr типа Integer. Если имя не найдено, создается объект Integer с единичным значением, в противном случае Integer создается с инкрементированным значением, взятым от предыдущего Integer. Новый объект Integer помещается в объект Session. Если вы используете этот же ключ в вызове setAttribute( ), то новый объект запишется поверх старого. Инкрементируемый счетчик используется для отображения числа визитов клиента во время этой сесии.



getAttributeNames( ) относится как к getAttribute( ), так и к setAttribute( ); он возвращает enumeration из имен объектов, прикрепленных к объекту Session. Цикл while в SessionPeek показывает этот метод в действии.

Вы можете быть удивлены как долго сохраняется объект Session. Ответ зависит от используемого вами контейнера сервлетов; по умолчанию обычно это длится до 30 минут(1800 секунд), это вы можете увидеть при вызове getMaxInactiveInterval( ) из ServletPeek. Тесты показывают разные результаты, в зависимости от контейнера сервлетов. Иногда объект Session может храниться всю ночь, но я никогда не видел случаю, чтобы объект Session исчезал раньше указанного неактивного интервала времени. Вы можете попробовать установить интервал неактивномти с помощью setMaxInactiveInterval( ) до 5 секунд и проверить очистится ли ваш объект Session через соответствующее время. Это может быть тот аттрибут, который вы захотите исследовать при выборе контейнера сервлетов.


Содержание раздела