English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Отслеживание сессии в Servlet

HTTP - это "несостоятельный" протокол, что означает, что каждый раз, когда клиент检索 веб-страницу, клиент открывает отдельное соединение с веб-сервером, и сервер автоматически не сохраняет никаких записей о предыдущих запросах клиента.

Но все же есть три способа поддерживать сеанс сессии между веб-клиентом и веб-сервером:

Cookies

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

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

Скрытые поля формы

Веб-сервер может отправить скрытое поле HTML-формы и уникальный идентификатор сеанса сессии, как показано ниже:

<input type="hidden" name="sessionid" value="12345">

Эта запись означает, что при отправке формы指定的 имя и значение автоматически включаются в данные GET или POST. Каждый раз, когда веб-браузер отправляет ответный запрос, значение session_id можно использовать для отслеживания различных веб-браузеров.

Это может быть эффективным способом поддержания отслеживания сеанса сессии, но щелчок по обычной гипертекстовой ссылке (A HREF...> не вызывает отправку формы, поэтому скрытые поля формы также не поддерживают обычное отслеживание сеанса сессии.

URL rewrite

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

Например, http://oldtoolbag.com/file.htm;sessionid=12345, сеансовый идентификатор добавлен как sessionid=12345, который может быть доступен веб-серверу для идентификации клиента.

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

Объект HttpSession

Кроме упомянутых выше трёх способов, Servlet также предоставляет интерфейс HttpSession, который предоставляет способ для идентификации пользователей и хранения информации о пользователях при работе с несколькими запросами или посещениями веб-сайта.

Servlet контейнер использует этот интерфейс для создания сеанса между HTTP клиентом и HTTP сервером. Сеанс длится определенный промежуток времени,跨多个连接或页面 запросы.

Вы можете получить объект HttpSession, вызывая общественный метод HttpServletRequest getSession() для получения объекта HttpSession, как показано ниже:

HttpSession session = request.getSession();

Необходимо вызвать перед отправкой любой документальной информации клиенту request.getSession(). Ниже приведен список нескольких важных методов, доступных в объекте HttpSession:

НомерМетод и описание
1public Object getAttribute(String name)
Этот метод возвращает объект, который имеет указанное имя в сеансе сессии, если объект с указанным именем не существует, то возвращает null.
2public Enumeration getAttributeNames()
Этот метод возвращает объект Enumeration String, который содержит имена всех объектов, привязанных к сеансу сессии.
3public long getCreationTime()
Этот метод возвращает время создания сеанса, начиная с полуночи 1 января 1970 года по Гринвичу, в миллисекундах.
4public String getId()
Этот метод возвращает строку, содержащую уникальный идентификатор, выделенный для сеанса.
5public long getLastAccessedTime()
Этот метод возвращает время последнего запроса клиента к сеансу, начиная с полуночи 1 января 1970 года по Гринвичу, в миллисекундах.
6public int getMaxInactiveInterval()
Этот метод возвращает максимальное время, в течение которого сеанс будет оставаться открытым, сохраняя контейнер Servlet, в секундах.
7public void invalidate()
Этот метод делает сеанс недействительным и解除 привязку всех объектов к нему.
8public boolean isNew()
Этот метод возвращает true, если клиент еще не знает о сеансе или если клиент решил не участвовать в сеансе.
9public void removeAttribute(String name)
Этот метод удаляет объект с указанным именем из сеанса.
10public void setAttribute(String name, Object value)
Этот метод привязывает объект к сеансу с указанным именем.
11public void setMaxInactiveInterval(int interval)
Этот метод устанавливает время между клиентскими запросами в секундах до того, как сеанс будет признан недействительным Servlet контейнером.

Пример отслеживания сеанса

Этот пример объясняет, как использовать объект HttpSession для получения времени создания сеанса и последнего доступа к сеансу. Если сеанс не существует, мы создадим новый сеанс через запрос.

package com.w3codebox.test;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
 /* Servlet implementation class SessionTrack */
 */
@WebServlet("/SessionTrack")
public class SessionTrack extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // 如果不存在 session 会话,则创建一个 session 对象
        HttpSession session = request.getSession(true);
        // 获取 session 创建时间
        Date createTime = new Date(session.getCreationTime());
        // 获取该网页的最后一次访问时间
        Date lastAccessTime = new Date(session.getLastAccessedTime());
         
        // 设置日期输出的格式  
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    
        String title = "Servlet Session 示例 - 基础教程网";
        Integer visitCount = new Integer(0);
        String visitCountKey = new String("visitCount");
        String userIDKey = new String("userID");
        String userID = new String("w3codebox");
        if(session.getAttribute(visitCountKey) == null) {
            session.setAttribute(visitCountKey, new Integer(0));
        }
    
        // Проверить, есть ли новый посетитель на странице
        if (session.isNew()){
            title = "Servlet Session пример - сайт основного руководства";
             session.setAttribute(userIDKey, userID);
        }
             visitCount = (Integer)session.getAttribute(visitCountKey);
             visitCount = visitCount + 1;
             userID = (String)session.getAttribute(userIDKey);
        }
        session.setAttribute(visitCountKey,  visitCount);
    
        // Установить тип содержимого ответа
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
    
        String docType = "<!DOCTYPE html>\n";
        out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#f0f0f0\">\n" +
                "<h1 align=\"center\">" + title + "</h1>\n" +
                 "<h2 align=\"center\">Сессия</h2>\n" +
                "<table border=\"1\" align=\"center\">\n" +
                "<tr bgcolor=\"#949494\">\n" +
                "  <th>Сессия</th><th>Значение</th></tr>\n" +
                "<tr>\n" +
                "  <td>id</td>\n" +
                "  <td>" + session.getId() + "</td></tr>\n" +
                "<tr>\n" +
                "  <td>Время создания</td>\n" +
                "  <td>" + df.format(createTime) + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Время последнего доступа</td>\n" +
                "  <td>" + df.format(lastAccessTime) + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>ID пользователя</td>\n" +
                "  <td>" + userID + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Статистика посещений:</td>\n" +
                "  <td>" + visitCount + "</td></tr>\n" +
                "</table>\n" +
                "</body></html>"); 
    }
}

Скомпилируйте上面的 Servlet SessionTrackИ создайте соответствующие записи в файле web.xml.

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <servlet> 
    <!-- Имя класса -->  
    <servlet-name>SessionTrack</servlet-name>
    <!-- Местоположение пакета -->
    <servlet-class>com.w3codebox.test.SessionTrack</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SessionTrack</servlet-name>
    <!-- Адрес доступа -->
    <url-pattern>/TomcatTest/SessionTrack</url-pattern>
  </servlet-mapping>
</web-app>

Введите это в строке адреса браузера http://localhost:8080/TomcatTest/SessionTrackПри первом запуске будет отображен следующий результат:

Попробуйте еще раз запустить этот же Servlet, и он покажет следующий результат:

Удаление данных сеанса сессии

Когда вы завершаете данные сеанса пользователя, у вас есть несколько вариантов:

  • Удаление определенного атрибута:Вы можете вызвать public void removeAttribute(String name) Метод для удаления значения, связанного с определенным ключом.

  • Удаление всего сеанса сессии:Вы можете вызвать public void invalidate() метод для удаления всей сессии сеанса.

  • метод для настройки времени сессии сеанса.Вы можете вызвать public void setMaxInactiveInterval(int interval) метод для отдельного настройки времени сессии сеанса.

  • Выход пользователя:Если используется сервер, поддерживающий servlet 2.4, вы можете вызвать logout Чтобы выйти из веб-сервера клиента и сделать все сессии всех пользователей неактивными.

  • Конфигурация web.xml:Если вы используете Tomcat, кроме вышеуказанного метода, вы можете настроить время сессии сеанса в файле web.xml следующим образом:

  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>

Время сессии в примере указано в минутах и заменит defaultValue 30 минут, установленный по умолчанию в Tomcat.

Метод getMaxInactiveInterval() в Servlet возвращает время сессии сеанса в секундах. Поэтому, если в web.xml настроено время сессии сеанса 15 минут, getMaxInactiveInterval() вернет 900.