Вы находитесь на странице: 1из 15

Cookies, sessions, scopes

Определение
• Куки — небольшой фрагмент данных, отправленный
веб-сервером и хранимый на компьютере
пользователя. Веб-клиент (обычно веб-браузер)
всякий раз при попытке открыть страницу
соответствующего сайта пересылает этот фрагмент
данных веб-серверу в составе HTTP-запроса.

Применяется для:
• аутентификации пользователя;
• хранения настроек пользователя;
• отслеживания состояния сеанса доступа пользователя;
• ведения статистики о пользователях.
Схема обмена cookie
Browser GET /message HTTP/1.0

200 OK
author=devstudy
Set-Cookie: author=devstudy

Server
Browser GET /message HTTP/1.0
Cookie: author=devstudy

author=devstudy 200 OK
Работа с Cookie
Cookie c = new Cookie("author", "devstudy");
c.setMaxAge(1800); // if negative,the cookie is not stored; if zero, deletes the cookie
c.setPath("/");
c.setHttpOnly(true);
resp.addCookie(c);

Cookie cookies[] = request.getCookies();


Преимущества и недостатки
Преимущества:
• Отслеживание сеанса пользователя;
• Пользовательские настройки;
• Направленная реклама;
• Использование cookie не представляет угрозы безопасности с точки зрения
атак;
• Браузеры принимают только 20 cookies на сайт и 300 всего, каждое Cookie до 4
кбайт – отсутствует проблема засорения жесткого диска.

Недостатки:
• Cookie могут подделываться для идентификации пользователя в качестве
другого;
• Cookie – открытые текстовые файлы. Поэтому в них нельзя хранить
конфиденциальную информацию. Обычно хранится только идентификатор –
данные в хеш-таблице или базе данных на сервере.
Отслеживание сеанса
HTTP – stateless протокол, каждый запрос –
отдельное соединение и сервер не имеет данных о
предыдущем запросе.

сессия

set get set get set get

page1 page2 page3


Организация сессий
Для организации сессий существует три типичных подхода:

• Cookies
response.addCookie(new Cookie("JSESSIONID", "84DF2A7638E3C402B3245D5D08B4BE43"));
• URL-rewriting
http://localhost:8080/page.jsp?jsessionid=84DF2A7638E3C402B3245D5D08B4BE43
http://localhost:8080/page.jsp;jsessionid=84DF2A7638E3C402B3245D5D08B4BE43
• Скрытые поля форм
<input type="hidden" name="JSESSIONID" value="84DF2A7638E3C402B3245D5D08B4BE43">

В Java Web-контейнерами обычно используются по умолчанию Cookies, но если браузер их


не поддерживает – автоматически осуществляется переход на URL-Rewriting.
Поддержка сессий осуществляется контейнером автоматически!

В случае использования cookies автоматически формируется Cookie с именем JSESSIONID.


Если cookie отключены, формируется URL вида: http://.../some_path;jsessionid=84DF2A

Это делается автоматически только в случае, если URL, к которому обращаются из Web-
приложения, закодирован методом
HttpServletResponse.encodeURL() или HttpServletResponse.encodeRedirectURL()

<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
Сессии в JEE
• Объект сессии создается автоматически каждый раз при получении запроса от нового
клиента и впоследствии идентифицирует его уникальным образом автоматически с
помощью Cookie;
• Разным пользователям и (или) браузерам соответствуют различные объекты сессий;
• Сессии "живут" на сервере в течение заданного времени, но только для одного
клиентского браузера!
<session-config>
<session-timeout>60</session-timeout>
</session-config>
• Позволяет сохранять данные, введенные клиентом в течение нескольких переходов по
страницам.
• Сессии – это то место где нужно хранить данные специфичные для конкретного клиента
web приложения!!!
• Получить ссылку на объект текущей HttpSession можно с помощью метода
request.getSession()
Сессии в JEE
Web-контейнер
HttpSession HttpSession
jsessionid=1 jsessionid=2
shoppingCart=A shoppingCart=B

jsessionid=1 jsessionid=1 jsessionid=1


set/get set/get set/get

page1 page2 page3


Данные, общие для всего
приложения
• Объект ServetContext существует в единственном экземпляре для одного WEB-
приложения.

Методы ServetContext:
• setAttribute (name, value) - сохраняет объект в глобальной области всего приложения
• value = getAttribute (name) - возвращает объект из глобальной области
• getRealPath (path) – возвращает реальный путь к ресурсу файловой системы,
находящемся по заданному виртуальному пути
• getResourceAsStream (path) – возвращает поток байт реального ресурса файловой
системы

Получить ссылку на ServletContext из сервлета можно, например, так:


• getServletContext()
или
• request.getSession().getServletContext()
Хранилища данных в приложении
Атрибуты можно устанавливать на уровне (scope):
1) JSP страницы (page)
pageContext.setAttribute("message", "Hello world");
String message = (String)pageContext.getAttribute("message");

2) Запроса (request)
request.setAttribute("message", "Hello world");
String message = (String)request.getAttribute("message");

3) Сессии (session)
request.getSession().setAttribute("message", "Hello world");
String message = (String)request.getSession().getAttribute("message");

4) Приложения (application)
getServletContext().setAttribute("message", "Hello world");
String message = (String)getServletContext().getAttribute("message");
Примеры использования
1) session.set/get/removeAttribute() – добавление, чтение и
удаление данных текущей сессии;
2) session.getAttributeNames() – список всех аттрибутов
сессии;
3) session.invalidate(); - запрос на удаление текущей сессии
и всех объектов, хранимых в ней (logout);
4) application.getRealPath(“/WEB-INF/setting-folder”) –
вернет абсолютный путь к папки с найстройками, чтобы
можно было считать конфигурационные файлы;
5) application.set/get/removeAttribute() – добавление,
чтение и удаление данных текущего контекста
приложения;
6) application.getAttributeNames() – список всех аттрибутов
текущего контекста приложения;
7) application.getContextPath() – вернет название
приложения, если оно не ROOT.war
Работа с Cookie
public final class WebUtils {
public static Cookie findCookie (HttpServletRequest req, String cookieName) {
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
if (c.getName().equals(cookieName)) {
if (c.getValue() != null && !"".equals(c.getValue())) {
return c;
}
}
}
}
return null;
}
public static void setCookie (String name, String value, int age, HttpServletResponse resp) {
Cookie c = new Cookie(name, value);
c.setMaxAge(age);
c.setPath("/");
resp.addCookie(c);
}
private WebUtils() {
}
}
Работа с пользовательской сессией
public class SessionUtils {
public static ShoppingCart getCurrentShoppingCart(HttpServletRequest req) {
ShoppingCart shoppingCart = (ShoppingCart)
req.getSession().getAttribute(Constants.CURRENT_SHOPPING_CART);
if (shoppingCart == null) {
shoppingCart = new ShoppingCart();
setCurrentShoppingCart(req, shoppingCart);
}
return shoppingCart;
}
public static boolean isCurrentShoppingCartCreated(HttpServletRequest req) {
return req.getSession().getAttribute(Constants.CURRENT_SHOPPING_CART) != null;
}
public static void setCurrentShoppingCart(HttpServletRequest req, ShoppingCart shoppingCart) {
req.getSession().setAttribute(Constants.CURRENT_SHOPPING_CART, shoppingCart);
}
public static void clearCurrentShoppingCart(HttpServletRequest req, HttpServletResponse resp) {
req.getSession().removeAttribute(Constants.CURRENT_SHOPPING_CART);
WebUtils.setCookie(Constants.Cookie.SHOPPING_CART.getName(), null, 0, resp);
}
public static Cookie findShoppingCartCookie(HttpServletRequest req){
return WebUtils.findCookie(req, Constants.Cookie.SHOPPING_CART.getName());
}
public static void updateCurrentShoppingCartCookie(String cookieValue, HttpServletResponse resp) {
WebUtils.setCookie(Constants.Cookie.SHOPPING_CART.getName(), cookieValue,
Constants.Cookie.SHOPPING_CART.getTtl(), resp);
}
private SessionUtils() {
}
}
Домашнее задание
1) Создать класс ShoppingCart, который будет хранить информацию о состоянии пользовательской
корзины;
2) В корзине можно хранить максимально 20 различных товаров;
3) Каждый товар, хранимый в корзине может иметь от 1 до 10 единиц. (Т.е максимально кол-во товаров
может быть 20 * 10 = 200;
4) В классе корзины нужно предусмотреть методы:
void addProduct(int idProduct, int count) throws ValidationException;
void removeProduct(Integer idProduct, int count);
Collection<ShoppingCartItem> getItems();
int getTotalCount();

5) Разработать формат сериализации состояния корзины в cookie;


6) Создать сериализатор и десериализатор:
String shoppingCartToString(ShoppingCart shoppingCart);
ShoppingCart shoppingCartFromString(String cookieValue);

5) Создать ShoppingCartServlet, назначение которого синхронизировать состояние корзины в HTTP сессии


и cookies.

Алгоритм работы сервлета:


1) Если в текущей HTTP сессии нет корзины, то нужно проверить есть ли cookie с состоянием корзины
2) Если cookie есть, то нужно десериализовать корзину из cookie и сохранить ее в HTTP сессию
3) Если в текущей HTTP сессии есть корзина, то нужно сериализовать корзину в String и добавить cookie с
обновленным состоянием корзины
4) Для тестирования данный сервлет должен добавлять случайный продукт в корзину