4.1 Знакомство с HttpSession

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

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

Объект сессии сохраняется на сервере, а ID отправляется в ответе клиенту и по умолчанию сохраняется на клиенте в куках. Затем, когда приходит новый запрос от того же клиента, то контейнер сервлетов достает из него ID, и по этому ID находит правильный объект HttpSession на сервере.

Получить объект сессии можно из запроса (объект HttpServletRequest), у которого нужно вызвать метод getSession(). Он возвращает объект HttpSession.

Зачем нужна сессия? В ней можно хранить информацию о клиенте между вызовами. У нее внутри есть что-то вроде HashMap, в котором можно хранить объекты по ключам. И несколько методов для этого:

Методы Описание
1 setAttribute(String name, Object o) Добавляет объект внутрь сессии
2 getAttribute(String name) Получает объект из сессии
3 removeAttribute(String name) Удаляет объект из сессии

Давай напишем сервлет, который будет суммировать все передаваемые ему числа из разных запросов:



public class CalculatorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
         // Получаем атрибут “sum” из сессии 
        HttpSession session = request.getSession();
        Integer sum = (Integer) session.getAttribute("sum");
        //Обрабатываем ситуацию, когда такого атрибута у сессии еще нет
        if (sum == null)
            sum = 0; 
 
         // Получаем параметр “n” из запроса
        String n = request.getParameter("n");
        sum += Integer.parseInt(n);
 
         // Записываем атрибут “sum” в сессию
        session.setAttribute("sum", sum);
 
        // Печатаем HTML в качестве ответа для браузера
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head> <title> CalculatorServlet </title> </head>");
        out.println("<body>");
        out.println("<h1> Sum == " + sum + "</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

4.2 Подробнее об HttpSession

Что еще важного мы не сказали об объекте HttpSession?

Во-первых, это имя JSESSIONID. Именно под ним в куках хранится ID сессии. Как видите, запомнить его довольно легко: J+SESSION+ID.

Во-вторых, у сессии есть еще несколько полезных методов:

Методы Описание
1 getAttributeNames() Возвращает список всех ключей, которые храниться в сессии
2 getId() Возвращает ID-сессии (строка)
3 isNew() Возвращает true, если объект сессии был создан в текущем запросе
4 setMaxInactiveInterval(int seconds) Устанавливает интервал неактивности сессии в секундах
5 invalidate() Удаляет из сессии все объекты

Тут все методы очевидны, а про setMaxInactiveInterval() мы поговорим немного подробнее.

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

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

По умолчанию этот интервал равен 1800 секундам == 30 минутам. Если установить значение -1, то сессия будет “вечной” и удалится только когда пользователь закроет вкладку браузера (ну или клиент разорвет соединение).

Примеры:


// получение всех ключей
Enumeration keys = session.getAttributeNames();
while( keys.hasMoreElements() ){
    System.out.println( (String) keys.nextElement() );
}

        

// установка интервала неактивности
session.setMaxInactiveInterval(60*60*24);   // 1 день
session.setMaxInactiveInterval(-1); // до закрытия браузера
        

// удаление всех данных из сессии
session.invalidate();