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>");
    }
}

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();