Сессия - это одна или несколько страниц, запрошенных клиентом на Web сайте во время определенного периода времени. Если вы покупаете продукты в режиме он-лайн, например, вы хотите, чтобы ваша сессия ограничивалась периодом от того момента, когда вы в первый раз добавили элемент в "свою корзину покупок" до момента, когда вы подтвердите выбор. Каждый добавленный вами элемент в корзину покупок будет результатом нового HTTP соединения, которое не знает о предыдущих соединениях или элементах в корзине покупок. Чтобы компенсировать этот недостаток информации, механизм обеспечивает спецификацию cookie, позволяющую вашему сервлету выполнить отслеживание сессии.
Объект сессии сервлета живет на серверной стороне коммуникационного канала; его целью является сбор полезных данных об этом клиенте, таких как перемещение клиента по сайту и взаимодействие с вашим Web сайтом. Эти данные могут относиться к текущей сессии и являться, например, элементами в корзине покупок, или это могут быть такие данные, как информация об авторизации, которая была введена клиентом при первом обращении к вашему Web сайту и поэтому ее не нужно вводить еще раз во время определенного набора транзакций.
Класс Session API сервлета использует класс Cookie, чтобы выполнить эту работу. Однако все объекты Session нуждаются в уникальном идентификаторе определенного рода, хранящемся у клиента и передающемся на сервер. Web сайты могут также использовать другие типы отслеживания сессии, но этот механизм будет более сложным для реализации, так как он не встроен в API сервлета (то есть, вы должны написать его руками, обработав ситуации, когда клиент отключает cookies).
Вот пример, который реализует отслеживание сессии с помощью API сервлета:
//: c15:servlets:SessionPeek.java
// Используем класс HttpSession.
// {Depends: j2ee.jar}
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( ). Причина для булевского значения состоит в объявлении состояния, с которым вы хотите создать объект сессии, если он не найден. 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 использует простые пары имя-значение для загрузки информации. Имя является строкой, а значение может быть любым объектом, наследованным от java.lang.Object. SessionPeek следит за там, сколько раз клиент возвращался назад во время этой сессии. Это выполняется с помощью объекта Integer, называемого sesspeek.cntr. Если име не найдено, создается Integer со значением равным единице, в противном случае Integer создается с инкрементированным значением по сравнению с предыдущим сохраненным Integer. Новый Integer помещается в объект Session. Если вы используете тот же самый ключ в вызове setAttribute( ), то новый объект переписывает старый. Инкрементированный счетчик используется для отображения количества визитов клиента во время этой сессии.
getAttributeNames( ) имеет отношение к getAttribute( ) и setAttribute( ); он возвращает перечисление имен объектов, которые включены в объект Session. Цикл while в SessionPeek показывает этот метод в действии.
Вы можете удивиться, как долго хранится объект Session. Ответ зависит от контейнера сервлетов, который вы используете; обычно, по умолчанию, это 30 минут (1800 секунд), что вы можете увидеть из вызова метода getMaxInactiveInterval( ) в ServletPeek. Тесты могут воспроизводить разные результаты в зависмиости от контейнера сервлетов. Иногда объект Session может храниться всю ночь, но я никогда не видел случая, когда объект Session исчезал в течение времени меньшего, чем указано в интервале не активности. Вы можете попробовать путем установки интервала не активности с помощью метода setMaxInactiveInterval( ) в значение 5 секунд и посмотреть, останется ли ваш объект Session или он будет очищен в соответствующее время. Это может стать атрибутом, который вы захотите исследовать при выборе контейнера сервлетов.
Запуск примеров сервлета
Если вы еще не работали с Сервером приложений, который обрабатывает сервлеты Sun и JSP технологию для вас, вы можете загрузить Tomcat реализацию Java сервлетов и JSP, которая является бесплатной реализацией с открытыми исходниками, санкционированная Sun. Tomcat можно найти на jakarta.apache.org.
Следуйте инструкциям для установки Tomcat реализации, затем отредактируйте файл server.xml, чтобы указать место в вашем дереве директорий, где будут размещены ваши сервлеты. Когда вы запустите программу Tomcat, вы сможете протестировать ваши сервлеты.
Заключение
Это была только короткая интродукция в сервлеты; есть целые книги, посвещенные этой теме. Однако это введение должно дать вам достаточно мыслей, чтобы начать. Кроме того, многие мысли следующего раздела имеют обратную совместимость с сервлетами.
← | Класс Cookie | Упражнения | → |