Управление сеансами в Java

Http-протокл работает по своей природе как запрос-ответ. Но иногда надо хранить информацию между запросами. Для этого разработан механизм сессии - позволяющий сохранять информацию между запросами одного пользователя.

Есть три способа отслеживания сессии:

1) cookies

2) переопределяемый URL (используется response.encodeURL для каждой ссылки, который вставляет идентификатор сессии в каждый URL.)

3) спрятанные поля HTML-страницы (в виде скрытых полей в форме)

Java предоставляет класс HttpSession, позволяющий автоматизировать всю работу с куками. Если куки поддерживаются, то response.encodeURL просто вернет свой параметр.

Пример создания куки: Cookie c = new Cookie (name, value); public interface HttpSession { public void invalidate; ...   } HttpSession session = request.getSession; - есть параметр нужно ли создать сессию.

При перенаправлении запросов надо использовать encoderRedirectURL

Для сессий можно назначать слушатейелй. Можно добавить на начало сессии и на привязку (добавление или удаление) аттрибутов.

Для этого используется HttpSessionBindingListener. после созранение вызывается valueBound и при удалении valueUnbind

Если используется кластер из контейнеров и Java-машин, то все объекты в сеансе должны реализовывать Serializable

Также сессиями можно управлять  в web.xml должен размещаться после servlet-mappings   20     время указано в секундах

Еще один способ декларативного управления времени жизни сесси через setMaxInactiveInterval(int seconds)

HttpSessionAttributeListener - реализуется отдельным классам, добавляющимся в настроки приложения, чем отличается от

HttpSessionBindingListener - должен реализовываться объектами, хранящимися в сессии

Продолжаем задачу ДЗ по созданию интернет-магазина.

В прошлый раз научились при помощи фильтра переадресовывать пользователя на страницу login.jsp. В этот раз авторизуем пользователя при помощи куки и стандартного Java-сеанса.

Если пользователь не авторизован для просмотра страницы webpage.jsp, то перенаправим его на страницу login.jsp?destination=webpage.jsp, где попросим ввести логин и пароль и перенаправим его на webpage.jsp.

Также создадим logout.jsp, в котором будем снимать авторизацию.

При этом проверять логин и пароль каком-либо способом пока не будем, веря пользователю "наслово".

Содержимое фильтра, который проверяет авторизован ли пользователь и, если не авторизован, пересылает его на login.jsp?destination= текущая страница

package jperm;

import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;

/** * * @author ars */ public class AuthFilter implements Filter { private FilterConfig filterConfig;

@Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; }

@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("doFilter is execute"); HttpServletRequest httpRequest = (HttpServletRequest) request; HttpSession session = httpRequest.getSession; String uriPath = httpRequest.getRequestURI.substring(httpRequest.getContextPath.length);     // Получаем путь до страницы типа /index.jsp или /login.jsp System.out.println("context path: " + httpRequest.getContextPath + " path: " + uriPath); if (session == null || session.getAttribute("userLogin") == null) {             // если сессия не создана // надо получить текущий url, чтобы по нему перенаправить потом с login.jsp HttpServletResponse httpResponse = (HttpServletResponse) response; // Мы не можем вызвать response.sendRedirect("login.jsp") так как нам нужен httpResponse, а не ServletResponse.

if ("login.jsp".equals(uriPath) || "logout.jsp".equals(uriPath)) { chain.doFilter(request, response); // вызываем следующий фильтр. }           // fixme надо добавить destination httpResponse.sendRedirect("login.jsp?destination=" + uriPath); return; }                       chain.doFilter(request, response);  // вызываем следующий фильтр. }

@Override public void destroy { this.filterConfig = null; } }

В login.jsp просим пользователя ввести userLogin и userPassword и, после этого, перенаправляем по адресу destination

<%@page contentType="text/html" pageEncoding="UTF-8"%> <%    //HttpSession userSession = request.getSession; System.out.println(session); if (session.getAttribute("userLogin") != null) {       // Если человек уже авторизован System.out.println("Пользователь авторизован. Зачем он пришел на login.jsp?"); response.sendRedirect("/");                                // то непонятно что он здесь делает и шлем его на главную }   if (request.getParameter("userLogin") != null && request.getParameter("userPassword") != null) { // В этом месте надо вставить аутентификацию пользователей. session.setAttribute("userLogin", request.getParameter("userLogin")); System.out.println("Пользователя авторизовали как " + session.getAttribute("userLogin") + "и теперь перенаправляем на index.jsp или на "+request.getParameter("destination")); // Отправляемся в destination или на главную страницу if (request.getParameter("destination") != null && !request.getParameter("destination").equals("") && !request.getParameter("destination").equals("/")) { // Если задан в post или get параметр destination try { System.out.println("Перенаправляем человека по адресу "+request.getParameter("destination")); response.sendRedirect(response.encodeRedirectURL(request.getContextPath + request.getParameter("destination"))); return; }           catch (Exception e) { response.sendRedirect("index.jsp"); return; }       }        response.sendRedirect("index.jsp"); }   System.out.println("Пользователь не авторизован, выведем форму авторизации."); System.out.println("userLogin: " + request.getParameter("userLogin")); %> <!DOCTYPE html>  Вход на сайт Введите Ваше имя и пароль   имя  пароль  '/>

В logout.jsp просто удаляем userLogin, чтобы фильтр посчитал человека неавторизованным и пересылаем пользователя по destination. Тут есть момент, что на самом деле сессию пользователя надо вычистить полностью, а не только стереть userLogin.

<%@page contentType="text/html" pageEncoding="UTF-8"%> <% if (session.getAttribute("userLogin") != null) {       // Если человек уже авторизован session.removeAttribute("userLogin"); if (request.getParameter("destination") != null ) { // Если задан в post или get параметр destination try { System.out.println("Перенаправляем человека по адресу "+request.getParameter("destination")); response.sendRedirect(request.getParameter("destination")); return; }       catch (Exception e) { response.sendRedirect("index.jsp"); return; }   }    response.sendRedirect("index.jsp"); return; } %>

<!DOCTYPE html>  Выход Вы вышли из системы! Перейти на главную страницу.

В web.xml надо прописать входной фильтр на все страницы, которые требуется защитить авторизацией

AuthFilter <filter-class>jperm.AuthFilter</filter-class> <filter-mapping> AuthFilter</filter-name> <url-pattern>/index.jsp</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>