Учебный курс по электронной коммерции в NetBeans - управление сеансами

Содержимое на этой странице применимо к IDE NetBeans, версии 6.8 и 6.9

Каждое приложение электронной коммерции, предлагающее какие-либо возможности корзины покупок, должно обладать функцией запоминания пользовательских данных в процессе перехода по веб-страницам/страницам веб-сайта. К сожалению, протокол HTTP, посредством которого осуществляется взаимодействие в Интернете, является протоколом без поддержки состояния. Каждый запрос, получаемый сервером, является независимым элементом данных, не связанным с ранее поступившими запросами. Поэтому при нажатии кнопки для добавления товара в корзину покупок приложение должно не только обеспечивать обновление корзины пользователя, но и предупреждать влияние данной корзины на корзины других пользователей, просматривающих сайт в это же время.

Чтобы правильно обработать описанный выше сценарий, необходимо реализовать функцию для создания и ведения сеанса на протяжении пребывания пользователя на сайте. Технология сервлета, являющаяся основой для всех веб-приложений на базе Java, предоставляет для этих целей интерфейс HttpSession. Также необходимо определить некоторые классы, а именно ShoppingCart и ShoppingCartItem, что позволит приложению хранить данные пользователя, пока время сеанса не истекло.

Подход данного раздела учебного курса отличается от остальных подходов, рассматриваемых в учебном курсе по электронной коммерции NetBeans. Вместо создания файлов проекта и предоставления пошаговых инструкций с фрагментами кода для копирования и вставки в собственный проект предлагается открыть пример готового проекта для данного раздела и изучить код при помощи отладчика среды IDE и других средств. В процессе работы будут изучены способы применения объекта HttpSession к коду, чтобы в результате каждого посещения веб-сайта создавался отдельный сеанс. Также будут рассмотрены контекстные переменные и их использование как в классах Java, так и на страницах JSP. Кроме того, в этом разделе описывается стандартный механизм HttpSession для ведения сеансов (например файлов cookie) и пошаговые инструкции, которые необходимо выполнить в случае деактивации файлов cookie в браузере пользователя. В заключение затрагивается время ожидания сеанса и демонстрируется принцип его обработки с созданием элементарного фильтра, перехватывающего запросы для проверки существования сеанса.

Можно просмотреть интерактивную демонстрацию приложения, которое создается в этом учебном курсе: Демонстрация приложения электронной коммерции NetBeans



Программное обеспечение или материал Требуемая версия
IDE NetBeans Набор Java, версия 6.8 или 6.9
Комплект для разработчика на языке Java (JDK) версия 6
Сервер GlassFish v3 или Open Source Edition 3.0.1
Сервер базы данных MySQL Версия 5.1
Проект AffableBean снимок 5

Примечания:

  • The IDE NetBeans requires the Java Development Kit (JDK) to run properly. Если указанные материалы не установлены, JDK следует загрузить и установить в первую очередь.
  • The IDE NetBeans Java Bundle includes Java Web and EE technologies, which are required for the application you build in this tutorial.
  • The IDE NetBeans Java Bundle also includes the GlassFish server, which you require for this tutorial. Можно загрузить сервер GlassFish отдельно, но версия, предоставляемая с NetBeans, имеет преимущество, так как автоматически зарегистрирована в среде IDE.
  • Этот учебный курс можно выполнять без выполнения предыдущих. Для этого обратитесь к инструкциям по настройке, в которых описана подготовка базы данных и настройка подключений между IDE, GlassFish, и MySQL.

Обработка данных сеанса

Приложения могут управлять пользовательскими сеансами при помощи объекта HttpSession. Можно привязать пользовательские данные к объекту HttpSession и получить возможность доступа к этим данным на дальнейших этапах. Операции привязки и доступа могут быть выполнены при помощи классов Java, а также переменных в контексте сеанса в выражениях на языке выражений.

Работа с объектом HttpSession

В приложении AffableBean используется объект HttpSession для идентификации пользователей при неоднократных запросах. Объект HttpSession можно получить при помощи метода getSession() для заданного запроса:

HttpSession session = request.getSession();

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

Объект сеанса можно использовать в качестве средства для передачи данных между запросами. Метод setAttribute используется для привязки объектов к сеансу. Таким же образом метод getAttribute используется для извлечения объектов из сеанса. Например, в приложении AffableBean корзина покупок пользователя создается и привязывается к пользовательскому сеансу следующим образом:

ShoppingCart cart = new ShoppingCart();
session.setAttribute("cart", cart);

Для извлечения корзины из сеанса применяется метод getAttribute:

cart = (ShoppingCart) session.getAttribute("cart");

На страницах JSP можно получить доступ к объектам, привязанным к сеансу с использованием выражений на языке выражений. Также, если объект ShoppingCart с именем cart привязан к сеансу, можно получить доступ к объекту при помощи следующего выражения на языке выражений:

${cart}

Доступ к объекту ShoppingCart сам по себе не представляет большого значения. Целью является доступ к значениям, хранящимся в объекте. При изучении нового класса ShoppingCart на снимке проекта обратите внимание, что он содержит следующие свойства:

  • удвоенный итог
  • int numberOfItems
  • List<String, ShoppingCartItem> items

При условии, что свойства соответствуют методам получения, можно получить доступ к значениям отдельных свойств при помощи простого точечного представления в выражении на языке выражений. На странице cart.jsp приведен точный способ доступа к свойству numberOfItems:

<p>Your shopping cart contains ${cart.numberOfItems} items.</p>

Для извлечения данных из свойств с несколькими значениями, например списка items, приведенного выше, на странице cart.jsp используется цикл <c:forEach>:

<c:forEach var="cartItem" items="${cart.items}" varStatus="iter">

  <c:set var="product" value="${cartItem.product}"/>

    <tr class="${((iter.index % 2) == 0) ? 'lightBlue' : 'white'}">
        <td>
            <img src="${initParam.productImagePath}${product.name}.png"
                 alt="${product.name}">
        </td>

        <td>${product.name}</td>

        <td>
            &euro; ${cartItem.total}
            <br>
            <span class="smallText">( &euro; ${product.price} / unit )</span>
        </td>
        ...
    </tr>

</c:forEach>

Принадлежащая ShoppingCartItem собственность product определяет тип продукта для элемента корзины. Цикл, рассматриваемый выше, использует результаты определения при первой установке переменной product в выражении ${cartItem.product}. Затем переменная используется для получения сведений об этом продукте (например имя, цена).

Работа с контекстными переменными в веб-приложениях

При работе с технологией JSP/сервлетов доступны четыре контекстных объекта в области приложения. Технология JSP реализует скрытые объекты, позволяющие получить доступ к классам, определяемым интерфейсом API сервлетов.

Контекст Определение Класс сервлетов Скрытые объекты JSP
Приложение Глобальная память веб-приложения javax.servlet.ServletContext applicationScope
Сеанс Данные пользовательского сеанса javax.servlet.http.HttpSession sessionScope
Запрос Данные отдельного запроса сервера javax.servlet.HttpServletRequest requestScope
Страница Данные, действительные только в контексте отдельной страницы (только JSP) неприменимо pageScope

При открытии файла category.jsp проекта в редакторе обратите внимание, что выражения на языке выражений включают в себя различные контекстные переменные, в частности, ${categories}, ${selectedCategory} и ${categoryProducts}. Переменная ${categories} находится в контексте приложения, устанавливаемого в методе init файла ControllerServlet:

// store category list in servlet context
getServletContext().setAttribute("categories", categoryFacade.findAll());

Остальные переменные, ${selectedCategory} и ${categoryProducts}, размещаются в контексте сеанса приложения в файле ControllerServlet. Например:

// place selected category in session scope
session.setAttribute("selectedCategory", selectedCategory);

Примечание. Если изучить предыдущие разделы руководства, можно заметить, что ${selectedCategory} и ${categoryProducts} были изначально помещены в область запроса. В предыдущих разделах такое размещение было целесообразным, но рассмотрим, что случится, если пользователь нажмет кнопку "добавить в корзину" на странице категорий. В ответ на запрос addToCart сервлет возвратит текущую страницу категорий. Таким образом нужно будет получить информацию о selectedCategory и categoryProducts, относящихся к выбранной категории. Вместо того чтобы узнавать данную информацию о каждом запросе, достаточно поместить ее в область сеанса запроса category, так чтобы она поддерживалась многими запросами и могла быть получена, когда в ней возникнет необходимость. Рассмотрим также функциональность страницы корзины. (Функции описываются ниже). Кнопка "Продолжить покупки" возвращает пользователя в предыдущую просмотренную категорию. Опять же запрашиваются переменные selectedCategory и categoryProducts.

При ссылке на контекстные переменные в выражении на языке выражений нет необходимости в указании контекста переменной (при условии отсутствия двух переменных с одинаковым именем в различных контекстах). Механизм JSP выполняет проверку всех четырех контекстов и возвращает первое найденное соответствие переменных. Например, в файле category.jsp выражение

${categoryProducts}

является сокращением для

${sessionScope.categoryProducts}
Для получения дополнительных сведений ознакомьтесь со следующими материалами:

Изучение данных сеанса при помощи отладчика Java

Начало изучения принципов поведения приложения во время выполнения. Используйте отладчик среды IDE для перехода по коду и изучения способов создания объекта HttpSession и размещения прочих объектов в контексте сеанса для их дальнейшего извлечения.

  1. Откройте пример проекта для данного раздела учебного курса в среде IDE. В диалоговом окне "Открытие проекта" ( Кнопка 'Открыть проект' ) перейдите к папке на компьютере, в которой хранится разархивированный файл учебного проекта. Если изучить предыдущий раздел руководства, можно заметить, что снимок проекта включает новый пакет cart, содержащий классы ShoppingCart и ShoppingCartItem. Также изменены следующие файлы:
    • WEB-INF/web.xml
    • css/affablebean.css
    • WEB-INF/jspf/header.jspf
    • WEB-INF/jspf/footer.jspf
    • WEB-INF/view/cart.jsp
    • WEB-INF/view/category.jsp
    • WEB-INF/view/checkout.jsp
    • controller/ControllerServlet
  2. Запустите проект ( Кнопка 'Выполнить проект' ), чтобы убедиться, что этот проект правильно настроен с помощью используемой базы данных и сервера приложений.

    Если при выполнении проекта выводится сообщение об ошибке, еще раз обратитесь к указаниям по настройке, в которых описаны принципы подготовки базы данных и установки соединения между средой IDE, сервером GlassFish и MySQL.

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

    страница категории

    • Первое нажатие кнопки "add to cart" активирует корзину покупок и виджеты "proceed to checkout", отображаемые в заголовке.
    • Нажатие кнопки "add to cart" приводит к обновлению числа товаров в виджете корзины покупок в заголовке.
    • В результате щелчка ссылки "view cart" отображается страница корзины.
    • При щелчке ссылки "proceed to checkout" открывается страница кассы.
    Изображение в браузере страницы категории

    страница корзины покупок

    • Щелчок ссылки "clear cart" обеспечивает удаление всех товаров из корзины покупок.
    • В результате щелчка ссылки "continue shopping" выполняется возврат к ранее просматриваемой категории.
    • При щелчке ссылки "proceed to checkout" открывается страница кассы.
    • Ввод числа (от 1 до 99) в поле количества товара и нажатие кнопки "update" запускает повторный расчет общей стоимости товара, а также промежуточной суммы.
    • При вводе нуля в поле количества товара и нажатии кнопки "update" товар удаляется из отображаемой таблицы.
    Изображение в браузере страницы покупательской корзины

    страница проверки

    • В результате щелчка ссылки "view cart" отображается страница корзины.
    • В результате нажатия "подтвердить покупку" на странице подтверждения отображаются результаты покупки (без указания информации о пользователе).
    Изображение в браузере страницы кассы
  4. Используйте диалоговое окно "Перейти к файлу", чтобы открыть файл ControllerServlet в редакторе. Нажмите ALT+SHIFT+O (CTRL+SHIFT+O в Mac OS), затем введите "Controller" в поле диалога и нажмите кнопку "ОК".
    Диалоговое окно 'Перейти к файлу'
  5. Установите точку останова в методе doPost на строке, которая создает объект HttpSession (строка 150). Для установки точки останова щелкните в левом поле редактора.
    Точка останова задана в редакторе

    Для переключения номеров строк в редакторе щелкните правой кнопкой мыши в левом поле и выберите команду "Показать номера строк".

  6. Запустите отладчик. Нажмите кнопку 'Отладка проекта' (Кнопка 'Отладка проекта') на главной панели инструментов IDE. Сервер GlassFish запускается (или перезапускается, если уже работал ) и открывает подключение через сокет по его отладочному номеру порта. В браузере откроется страница приветствия приложения.

    Можно просматривать и изменять номер порта отладки в диалоговом окне "Серверы" ("Сервис" > "Серверы"). Выберите вкладку "Java" для используемого сервера. Укажите номер порта в поле "Используемый адрес" под заголовком "Параметры отладки".

  7. При выводе страницы приветствия в браузере выберите категорию и добавьте несколько элементов в корзину покупок. Следует помнить, что нажатие кнопки "add to cart" отправляет запрос addToCart на сервер:
    <form action="addToCart" method="post">
    Как уже было описано в разделе Подготовка представлений страницы и сервлета контроллера, принадлежащий ControllerServlet метод doPost поддерживает запросы URL-адреса шаблона /addToCart. Следовательно, при нажатии кнопки "add to cart" ожидается вызов метода doPost.
  8. Нажмите кнопку "add to cart" для любого элемента на странице категорий. Перейдите к среде IDE и обратите внимание, что отладчик приостановил работу в точке останова.
    Отладчик приостанавливает работу по достижении точек останова, заданных в редакторе
  9. Поместите курсор в месте вызова метода getSession() и нажмите сочетание клавиш CTRL+ПРОБЕЛ для вывода документации Javadoc.
    Документация Javadoc, отображаемая в редакторе
    В соответствии с документацией метод getSession() возвращает объект HttpSession, связанный в настоящее время с запросом, и (при отсутствии сеанса) создает новый объект сеанса.

  10. Наведите курсор на переменную session. Обратите внимание, что отладчик приостанавливает работу на строке, которая должна быть запущена в нем. Значение, возвращаемое getSession() еще не сохранено в переменной session и отображается всплываюшщее окно, в котором указывается, что "session не является известной переменной в текущем контексте".
    Всплывающее окно отладчика отображается в редакторе
  11. Нажмите кнопку 'Обход процедур' (Кнопка 'Обход процедур') в отладчике на панели инструментов, расположенной выше в редакторе. Строка обрабатывается, и отладчик переходит к следующей строке файла.
  12. Снова наведите курсор на переменную session. Можно увидеть, что текущее значение сохранено в переменной session.
    Всплывающее окно отладчика отображается в редакторе

    В NetBeans 6.9 можно щелкнуть серый указатель ( Кнопка 'Обход процедур' ) во всплывающем окне, чтобы расширить список значений переменных, содержащихся в выделенном элементе.

  13. Нажмите кнопку 'Обход процедур' ( Кнопка 'Обход процедур' ) (F8; fn-F8 в Mac) для перехода к оператору if (строка 154). Поскольку в браузере только что была нажата кнопка "add to cart", выражение userPath.equals("/addToCart") должно иметь значение true.
  14. Выделите выражение userPath.equals("/addToCart") (нажав клавишу CTRL и щелкнув клавишей мыши). При этом будет выведено всплывающее окно со значением выделенного выражения.
    Оцениваемое выражение отображается во всплывающем окне
  15. Нажмите клавишу F8 (fn-F8 в Mac OS) для перехода к следующей строке (строка 158). Приложение спроектировано таким образом, что объект ShoppingCart создается для пользовательского сеанса только при первом добавлении элемента в корзину пользователя. Поскольку запрос addToCart в этом сеансе отладки получен впервые, предполагается, что объект cart имеет значение null.
    Оцениваемое выражение отображается во всплывающем окне
  16. Нажмите клавишу F8 (fn-F8 в Mac OS) для перехода к следующей линии (линия 160). Затем в строке 160, где создан объект ShoppingCart, нажмите кнопку 'Вход в' ( Кнопка 'Вход в' ). Отладчик переходит к вызываемому методу. В этом случае выполняется переход непосредственно к конструктору файла ShoppingCart.
    Оцениваемое выражение отображается во всплывающем окне
  17. Нажмите сочетание клавиш CTRL+TAB для перехода к файлу ControllerServlet. Обратите внимание, что IDE предоставляет значок 'Стек вызовов' ( Метка "Стек вызовов" ) в строке 160, указывая, что отладчик в настоящее время приостановлен где-то на методе выше в стеке вызовов.

    Нажмите ALT+SHIFT+3 (CTRL+SHIFT+3 в Mac OS), чтобы открыть окно стека вызовов.

  18. Нажмите клавишу F8 (fn+F8 в системе Mac) для продолжения перехода по коду. При завершении обработки отладчиком конструктора ShoppingCart выполняется возврат к файлу ControllerServlet.

    Строка 161 ControllerServlet привязывает вновь созданный объект cart к сеансу.
    session.setAttribute("cart", cart);
    Чтобы в этом удостовериться, откройте окно переменных отладчика. Выберите "Окно" > "Отладка" > "Переменные" или нажмите ALT+SHIFT+1 (CTRL+SHIFT+1 в Mac OS).
    Окно "Переменные"
    При последовательной развертке узлов "session" > "session" > "attributes" можно просмотреть объекты, привязанные к сеансу. На изображении выше отображены два элемента, привязанные в настоящее время к сеансу (выделены на снимке). Это selectedCategory и categoryProducts, показанные в ControllerServlet на строках 83 и 89, соответственно. Оба элемента были привязаны ранее при щелчке изображения категории и обработке запроса страниц категории в файле ControllerServlet.
  19. Нажмите клавишу F8 (fn-F8 в Mac OS) для выполнения кода со строки 161. Объект cart привязывается к сеансу, и диалоговое окно "Переменные" обновляется для отображения изменений. Обратите внимание, что в окне "Переменные" сеанс содержит в настоящий момент три атрибута, третьим атрибутом является только что инициализированный объект ShoppingCart (выделен на снимке ниже).
    Окно "Переменные"

    Пока что не было "доказано", что сеанс, как указано в диалоговом окне "Переменные", представляет объект HttpSession. Как упоминалось выше, HttpSession фактически является интерфейсом, так что при рассмотрении объекта HttpSession или объекта сеанса фактически имеется в виду любой объект, реализующий интерфейс HttpSession. При наведении курсора мыши в диалоговом окне "Переменные" на элемент session будет выведено всплывающее окно, указывающее на то, что переменная представляет объект HttpSession. Тип StandardSessionFacade, отображенный на снимке, является внутренним классом, используемым сервером GlassFish для реализации интерфейса HttpSession. При наличии опыта работы с Tomcat обратите внимание, что пути org.apache.catalina в столбце "Значение" обусловлены тем, что веб-контейнер/контейнер сервлета GlassFish фактически является производным от контейнера Apache Tomcat.

    В сеанс добавляется новый объект ShoppingCart, и запрос продолжает обрабатываться. Для завершения реализации функции "add to cart" предпринимаются следующие действия:
    • Идентификатор выбранного продукта получается из запроса (строка 165).
    • Объект Product создается с помощью идентификатора (строка 169).
    • Новый экземпляр ShoppingCartItem создается с помощью product (строка 170).
    • Экземпляр ShoppingCartItem добавляется в состоящий из ShoppingCartItem список экземпляров (строка 170).
  20. Нажмите клавишу F8 (fn+F8 в системе Mac OS), чтобы продолжить выполнение перехода по коду с учетом перечисленных выше четырех действий. Сделайте паузу, когда отладчик временно остановится на строке 170.
  21. Создайте наблюдение за сеансом. Эта функция позволит просматривать значения, содержащиеся в сеансе, при переходе к методу addItem в следующем шаге. Щелкните правой кнопкой мыши сеанс в диалоговом окне "Переменные" и выберите команду "Установить постоянное наблюдение".
    Контекстное меню отображается в окне 'Переменные'

    Кроме того, вы можете поместить курсор на переменной session в редакторе, а затем щелкнуть правой кнопкой мыши и выбрать 'Новое наблюдение'. Диалоговое окно создания наблюдения позволяет определить переменные или выражения для постоянного наблюдения за отладкой приложения. (При использовании выражений, сначала выделите выражение, а затем щелкните правой кнопкой мыши и выберите 'Новое наблюдение').
    Диалоговое окно 'Соблюдать наблюдение'

    Для переменной session и всех содержащихся в ней переменных создается наблюдение. Наблюдение отображается в окне 'Наблюдения' (Window > 'Отладка' > 'Наблюдения') или при переключении кнопки наблюдений ( Кнопка 'Наблюдения' ) на левой границе окна 'Переменные' оно отображается в верхней строке окна 'Переменные'.

    Отладчик позволяет наблюдать за переменными по мере перехода по коду. Это важно, например, при отслеживании изменения для отдельных значений переменных (без просмотра полного списка в окне "Переменные" для каждого шага) или при временном переходе к классу, не содержащему рассматриваемые переменные.
  22. Нажмите кнопок 'Вход в' ( Кнопка 'Вход в' ) для перехода к ShoppingCart к методу addItem.
  23. Последовательно шагайте по методу addItem, пока не достигните строки 53. Согласно документации Javadoc addItem "добавляет элементShoppingCartItem в список items в файле ShoppingCart. Если указанный товар из списка product уже существует в списке корзины покупок, количество этого товара увеличивается."
  24. Изучите переменную session, для которой был создан параметр наблюдения (шаг 21 выше). Выражение items.add(scItem) на странице 51 добавляет новый экземпляр ShoppingCartItem в список items в ShoppingCart. Этот процесс можно проследить при переходе к третьему атрибуту, содержащемуся в сеансе (например, переменной cart).
    Окно "Переменные"
    На данном этапе можно изучить принцип создания HttpSession для запроса, создания объекта ShoppingCart и его прикрепления к сеансу, а также создания элемента ShoppingCartItem на основе пользовательского выбора продукта с последующим добавлением в список items файла ShoppingCart. Последним действием является переадресация запроса в представление category.jsp.
  25. Откройте в редакторе фрагмент JSP заголовка (header.jspf) и разместите точку останова в строке 86. Эта строка содержит оператор на языке выражений в пределах виджета корзины покупок, отображающего число элементов корзины.
    Точка останова задана на странице JSP
  26. Нажмите кнопку 'Продолжить' ( Кнопка 'Продолжить' ) на панели инструментов отладчика. Отладчик продолжает работу до завершения обработки или до следующей точки останова. В последнем случае отладчик приостанавливается на строке 86 фрагмента JSP заголовка.

    Примечание. Чтобы отложить работу отладчика на странице JSP требуется контрольная точка. Например, если в файле ControllerServlet выполняется переадресация запроса в соответствующее представление, отладчик не будет автоматически приостановлен на странице JSP.

  27. Откройте окно переменных (ALT+SHIFT+1; CTRL+SHIFT+1 в системе Mac OS), если оно еще не открыто. В отличие от классов Java отладчик не предоставляет подсказки при наведении курсора мыши на переменные или выражения на странице JSP. Однако диалоговое окно "Переменные" не позволяет определять значения переменных при переходе по коду. Где можно найти значение для переменной ${cart.numberOfItems}?
  28. Последовательно разверните в диалоговом окне "Переменные" узлы "Скрытые объекты" > "pageContext" > "session" > "session" > "attributes". В результате будет предоставлен доступ к объекту сеанса, как и при работе с файлом ControllerServlet. Обратите внимание, что сеанс, для которого на шаге 21 было создано наблюдение, указывает на сам объект. Здесь можно убедиться, что значение переменной ${cart.numberOfItems} составляет "1".
    Окно "Переменные"

    Разверните окно 'Переменные' или любое окно в IDE, щелкнув правой кнопкой мыши заголовок окна, а затем выбрав 'Развернуть окно' (Shift-Esc).

    Отладчик предоставляет доступ к скрытому объекту pageContext. pageContext предоставляет контекст страницы JSP и открывает прямой доступ к различным объектам, включая объекты HttpServletRequest, HttpSession и ServletContext. Для получения дополнительных сведений обратитесь к Учебному курсу по Java EE 5: скрытые объекты.
  29. Нажмите кнопку 'Завершить сеанс' ( Кнопка 'Завершить сеанс' ). Работа среды выполнения и сеанса отладки завершается. Браузер отображает страницу категорий с полной визуализацией, и виджет корзины покупок в заголовке страницы содержит один элемент.

Надеемся, что теперь использование отладчика среды IDE не только для анализа проекта при неожиданном поведении, но и в качестве средства изучения кода, не вызывает у вас затруднений. Ниже перечислены другие функциональные кнопки на панели инструментов:

  • ( Кнопка 'Выход' ) Выход. Выполняется выход из вызова текущего метода. Выполняется обработка и удаление самого верхнего вызова метода в стеке вызовов.
  • ( Кнопка 'Переход к курсору' ) Переход к курсору Выполнение до строки, на которой размещен курсор.
  • ( Кнопка 'Применить изменения кода' ) Применить изменения кода. После редактирования файла можно нажать эту кнопку, чтобы файл был повторно скомпилирован и изменения учитывались в сеансе отладки.
  • ( Кнопка 'Выражение обхода процедур' ) Выражение обхода процедур. Позволяет просматривать входные параметры и получаемые выходные значения всех вызовов методов в выражении. Можно изучить выходные значения для предыдущего метода и входные параметры для следующего метода в диалоговом окне "Локальные переменные". При отсутствии дальнейших вызовов методов, режим работы выражения обхода процедур аналогичено команде Step Over ( Кнопка 'Обход процедур' ).

Изучение параметров отслеживания сеанса

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

Проект AffableBean включает в себя пример метода скрытого поля на странице категорий и корзины. Кнопки "add to cart" и "update", отображаемые для элементов продукта, содержат скрытое поле, передающее идентификатор продукта на сервер при нажатии кнопки. При открытии страницы cart.jsp в редакторе можно заметить, что теги <form> содержат скрытое поле.

<form action="updateCart" method="post">
    <input type="hidden"
           name="productId"
           value="${product.id}">
    ...
</form>

Таким образом, идентификатор продукта отправляется в виде параметра запроса, используемого сервером для идентификации элемента в пользовательской корзине, количество которой необходимо изменить.

Интерфейс API сервлета предоставляет высокоуровневый механизм для управления сеансами. Фактически он создает и передает файлы cookie между клиентом и сервером в каждом цикле "запрос-ответ". Если браузер клиента не принимает файлы cookie, механизм сервлета автоматически возвращается к перезаписи URL-адреса. Следующие два упражнения демонстрируют работу этой функции.

Изучение обмена данными между сервером и клиентом с использованием монитора HTTP

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

Для наглядности отладчик используется вместе с монитором HTTP среды IDE.

  1. Начните работу с активации монитора HTTP для используемого сервера. Выберите элементы "Сервис" > "Серверы". В левом столбце окна "Серверы" выберите используемый сервер (GlassFish). Затем выберите на главной панели режим "Включить монитор HTTP".
    Окно 'Серверы'
  2. Если сервер уже запущен, необходимо перезапустить его. Однако поскольку планируется использование отладчика, а при запуске отладчика выполняется перезапуск сервера для взаимодействия с другим портом, просто нажмите кнопку 'Отладка проекта' ( Кнопка 'Отладка проекта' ) на главной панели инструментов IDE. Будет выполнена перезагрузка сервера, запустится сеанс отладки, и в браузере откроется страница приветствия приложения. В нижней области среды IDE будет отображен монитор HTTP.
    Монитор HTTP
  3. Щелкните запись AffableBean в левом столбце (как показано на снимке выше). При выборе записей в левом столбце правый (т.е. главный) столбец обновляется для отображения соответствующих данных. На изображении выше вкладка "Запрос" отображает идентификатор URI запроса (/AffableBean/), метод HTTP (GET) и указывает на отсутствие отправки строки запроса вместе с запросом.
  4. Выберите вкладку "Сеанс". Обратите внимание на утверждение: "Сеанс создан в результате этого запроса." Это вызвано отправкой сервером заголовка Set-Cookie для файла cookie JSESSIONID в качестве ответа. Также обратите внимание, что новый идентификатор сеанса указан в области "Свойства сеанса". Как будет продемонстрировано ниже, идентификатор сеанса представляет собой значение файла cookie JSESSIONID.
    Монитор HTTP - вкладка "Сеанс".
    Может возникнуть вопрос о способе создания объекта сеанса из запроса для страницы приветствия сайта. Ведь в файле ControllerServlet не выполняется обработка начального запроса для /AffableBean/, и этот запрос нигде не сталкивается с методом getSession(). Или сталкивается? Напомним, что страницы JSP скомпилированы в сервлеты при развертывании. При первом развертывании проекта на сервере можно фактически использовать среду IDE для просмотра скомпилированного сервлета JSP на собственном сервере.
  5. В окне 'Проекты' щелкните правой кнопкой мыши файл index.jsp и выберите 'Просмотреть сервлет'. В редакторе откроется файл index_jsp.java. Файл является сервлетом, автоматически скомпилированным на основе страницы index.jsp.
  6. Выполните в файле поиск метода getSession. Нажмите Ctrl-F (⌘-F в Mac), введите 'getSession' на панели поиска, затем нажмите кклавишу Enter.

    Ctrl-F (⌘-F в Mac) - это сочетание клавиш для 'Правка' > 'Найти'.

    В редакторе отображается метод getSession
    Фактически выполняется вызов метода getSession. Это вызвано тем, что страницы JSP по умолчанию включают в себя скрытый объект pageContext.session. Для деактивации этого поведения можно добавить следующую директиву в верхнюю область файла JSP:
    <%@page session="false" %>
    , и методgetSession в скомпилированном сервлете будет деактивирован.

    Для выяснения местоположения скомпилированного сервлета на сервере можно навести курсор мыши на вкладку с именем сервлета над редактором. Будет выведено всплывающее окно с путем к файлу на компьютере.

  7. Выберите категорию в браузере и добавьте товар в корзину. Перейдите в среду IDE. Заметим, что отладчик приостанавливает работу на точке останова в ControllerServlet, поставленную ранее (на строке 150). Все точки останова между сеансами запоминаются. Для удаления точки останова можно щелкнуть метку точки останова ( Метка точки останова ) на левой границе редактора. Тем не менее, поскольку в проект уже добавлено несколько точек останова, откройте окно отладчика "Точки останова" ("Окно" > "Отладка" > "Точки останова").
    Окно 'Точки останова'
    В окне "Точки останова" можно просматривать и вызывать действия для всех точек останова, установленных в проектах, которые открыты в среде IDE.
  8. Щелкните правой кнопкой мыши точку останова, установленную в файле header.jspf, и выберите команду "Удалить". Then щелкните правой кнопкой мыши the breakpoint set in the ControllerServlet and choose Disable. (Позднее в этом упражнении будет выполнено ее повторное включение).
  9. Нажмите кнопку 'Продолжить' ( Кнопка 'Продолжить' ). Обработка запроса завершается, и на странице категорий браузера выводится добавленный в корзину товар.
  10. В мониторе HTTP выполните поиск запроса addToCart в левом столбце, затем выберите его для отображения подробных данных в главном столбце.

    Нажмите кнопку 'Сортировка по возрастанию' ( Кнопка 'Сортировка по возрастанию' ), чтобы последние записи были указаны в верхней части.


    Обратите внимание на идентификатор URI запроса (/AffableBean/addToCart), метод HTTP (POST) и параметры запроса (productId и submit) на вкладке "Запрос".
    Монитор HTTP - вкладка "Запрос".
  11. Выберите вкладку "Файлы cookie". Здесь отображаются данные о существовании файла cookie с именем JSESSIONID и его отправке от клиента на сервер. Обратите внимание, что значение файла cookie совпадает с идентификатором сеанса, отображаемом на вкладке "Сеанс".
    Монитор HTTP - вкладка "Файлы Cookies".
    Схожие данные представлены на вкладке "Заголовок", на которой отображается файл cookie, поскольку Cookie является заголовком запроса, отправленного клиентом.
    Монитор HTTP - вкладка "Файлы Cookies".

    Для получения дополнительных сведений о заголовках запроса и ответа обратитесь к странице веб-энциклопедии Wikipedia Список заголовков HTTP.

  12. Выберите вкладку "Сеанс". На вкладке отображается сообщение "Сеанс предшествует запросу". Также обратите внимание, что атрибут cart отображается в списке "Атрибуты сеанса после запроса". И это объяснимо, ведь объект cart привязывается к сеансу при первой обработке запроса addToCart.
    Монитор HTTP - вкладка "Сеанс".

    В следующих нескольких шагах рассматривается поиск идентификатора сеанса и файла cookie JSESSIONID в диалоговом окне "Переменные".
  13. Снова активируйте точку останова, ранее установленную в файле ControllerServlet. Нажмите ALT+SHIFT+5 (CTRL+SHIFT+5 в Mac OS), чтобы открыть окно точек останова, затем установите флажок напротив точки останова, чтобы включить ее заново.
  14. Нажмите в браузере кнопку "add to cart" для одного из перечисленных продуктов.
  15. Перейдите в среду IDE и обратите внимание, что отладчик приостановился на точке останова, установленной в файле ControllerServlet. Нажмите кнопку 'Обход процедур' ( Кнопка 'Обход процедур' ) для назначения переменной session объекту сеанса.
  16. Откройте окно "Переменные" (ALT+SHIFT+1; CTRL+SHIFT+1 в Mac OS), чтобы развернуть session > session. Идентификатор сессии будет указан в качестве значения переменной id.
  17. При поиске файла cookie JSESSIONID следует помнить, что обычно файл cookie доступен из сервлета при вызове метода getCookies в объекте HttpServletRequest. Поэтому перейдите к объекту запроса по пути: "request" > "Inherited" > "request" > "request" > "Inherited" > "cookies". Здесь можно просмотреть список файлов cookie ArrayList. При развертке списка можно найти файл cookie JSESSIONID, значением которого является идентификатор сеанса.
  18. Нажмите кнопку 'Завершить сеанс' ( Кнопка 'Завершить сеанс' ), чтобы завершить сеанс отладки.

Ведение сеансов с перезаписью URL-адреса

Как упоминалось выше, механизм сервлета обнаруживает возможность поддержки файлов cookie в браузере клиента, в случае невозможности поддержки механизм переходит к перезаписи URL-адреса как способа ведения сеансов. Эти процессы являются прозрачными для клиента. Для разработчиков процесс не является полностью прозрачным.

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

Например, браузер отправляет запрос для третьей категории приложения AffableBean (bakery): category?3. Сервер отправляет в ответ идентификатор сеанса, включенный в URL-адрес:

/AffableBean/category;jsessionid=364b636d75d90a6e4d0085119990?3

Как описано выше, все URL-адреса, возвращенные сервлетами приложения, необходимо зашифровать. Помните, что страницы JSP компилируются в сервлеты. Как зашифровать URL-адреса на страницах JSP? Для этих целей необходимо использовать тег <c:url> JSTL. Следующие упражнения демонстрируют проблему и ее решение.

  1. Временно отключите файлы cookie в браузере. При использовании Firefox можно выбрать пункт "Настройки" в меню "Инструменты" ("Firefox" > "Параметры" в системе Mac). Выберите в открывшемся диалоговом окне вкладку "Приватность", затем выберите в области "История" пункт "будет использовать ваши настройки хранения истории" в предоставленном раскрывающемся списке. Снимите флажок параметра "Принимать cookie с сайтов".
    Окно предпочтений Firefox
  2. Запустите проект AffableBean. При отображении страницы приветствия щелкните категорию и попытайтесь добавить элемент в корзину. Обратите внимание, что функциональные возможности приложения строго ограничены.
    Страница 'Некорректные категории'
    Как и ранее, сервер создает сеанс и привязывает к нему объекты. Это метод для отображения выбранной категории и продуктов на странице категорий. Тем не менее, при попытке установить файл cookie JSESSIONID на сервере происходит сбой. Следовательно, при повторном запросе клиента (когда пользователь нажмите кнопку "add to cart") сервер не может определить сеанс, к которому относится запрос. Поэтому невозможно найти атрибуты, ранее установленные в сеансе, например selectedCategory и categoryProducts. По этой причине в отображаемом ответе отсутствуют данные, определяемые этими атрибутами.
  3. Откройте в редакторе страницу category.jsp проекта. Найдите строку, в которой реализуется кнопка "add to cart" (строка 58). Атрибут action элемента <form> определяет запрос, отправленный на сервер.
    <form action="addToCart" method="post">
  4. Измените запрос для его передачи посредством тега <c:url>.
    <form action="<c:url value='addToCart'/>" method="post">
  5. Для сохранения изменений в файле нажмите сочетание клавиш CTRL+S (⌘-S в Mac). Помните, что среда IDE предоставляет функцию "Развертывание при сохранении", которая активна по умолчанию. Это означает, что все сохраненные изменения автоматически разворачиваются на сервере.
  6. Выберите в браузере другую категорию для отображения в приложении измененной страницы категорий.
  7. Изучите исходный код страницы. В Firefox можно нажать Ctrl-U (⌘-U в Mac). Отобразится кнопка "add to cart" для каждого продукта с идентификатором сеанса, добавленным к URL-адресу.
    <form action="addToCart;jsessionid=4188657e21d72f364e0782136dde" method="post">
  8. Нажмите кнопку "add to cart" для любого товара. Теперь сервер способен определить сеанс, которому принадлежит запрос, и создает соответствующий ответ.
  9. Перед продолжением убедитесь, что файлы cookie в браузере снова включены.

Снова возникает необходимость в шифровании каждой активной ссылки приложения, ответ которой требует определенной формы данных сеанса. Иногда реализация выполняется не так очевидно, как описывается в примере выше. Например, в настоящий момент виджет "clear cart", используемый на странице cart.jsp, устанавливает для параметра clear значение true при щелчке ссылки.

<%-- clear cart widget --%>
<c:if test="${!empty cart && cart.numberOfItems != 0}">
    <a href="viewCart?clear=true" class="bubble hMargin">clear cart</a>
</c:if>

Тег <c:url> можно применить к URL-адресу следующим образом:

<%-- clear cart widget --%>
<c:if test="${!empty cart && cart.numberOfItems != 0}">

    <c:url var="url" value="viewCart">
        <c:param name="clear" value="true"/>
    </c:url>

    <a href="${url}" class="bubble hMargin">clear cart</a>
</c:if>

Параметр clear=true устанавливается путем добавления тега <c:param между тегами <c:url>. Переменная url устанавливается при помощи атрибута var тега <c:url>, затем доступ к атрибуту var осуществляется в теге привязки HTML с использованием выражения ${url}.

Можно загрузить и изучить снимок 6 для просмотра способа шифрования всех ссылок проекта.

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


Обработка истечения времени ожидания сеанса

Установка временных интервалов сеанса

Необходимо учитывать максимальный интервал времени, в который выполняется ведение сеансов. Если веб-сайт обрабатывает большой поток данных, большое число сеансов может занять весь объем памяти. Следовательно, необходимо сократить интервал для удаления неиспользуемых сеансов. С другой стороны, следует избегать излишнего сокращения сеансов, поскольку это может привести к проблемам использования веб-сайта, сказывающимся на эффективности работы. В примере проекта AffableBean пользователь переходит к кассе после заполнения корзины покупок товарами. Затем пользователь выходит из сети, например, чтобы найти кредитную карту для ввода данных карты. После входа в сеть пользователь заполняет форму на кассе и нажимает кнопку подтверждения. Однако время ожидания сеанса на сервере уже истекло. Корзина покупок становится пустой, и пользователь перенаправляется на домашнюю страницу. Найдется ли у пользователя время на повторение процесса?

Следующие шаги демонстрируют способы установки в проекте AffableBean в качестве интервала для истечения времени ожидания сеанса значения в 10 минут. Конечно, фактическая длительность в конечном счете зависит от ресурсов сервера, бизнес-целей приложения и популярности веб-сайта.

  1. Откройте в редакторе дескриптор развертывания приложения. Нажмите ALT+SHIFT+O (CTRL+SHIFT+O в Mac OS) для использования диалога "Перейти к файлу". Введите "web", затем нажмите кнопку "ОК".
    Диалоговое окно 'Перейти к файлу'
    В редакторе будет выведен файл web.xml в представлении XML. Шаблон, предоставляемый NetBeans для файла web.xml, включает в себя по умолчанию параметр с интервалом в 30 минут.
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
  2. Выберите вкладку "Общее" и введите в поле "Время ожидания сеанса" значение "10".
    Вкладка 'Общие' файла web.xml
  3. Сохраните файл (сочетание клавиш Ctrl-S; ⌘-S в Mac).

    При обратном переходе в представление XML можно заметить, что элемент <session-timeout> был обновлен.
    <session-config>
        <session-timeout>10</session-timeout>
    </session-config>

Примечание. В качестве альтернативы вы можете полностью удалить элемент <session-timeout> и изменить элемент session-properties в дескрипторе развертывания, связанном с GlassFish (sun-web.xml). В результате будет установлено глобальное время ожидания для всех приложений в веб-модуле сервера. Получить более подробную информацию можно в руководстве Oracle GlassFish Server 3.0.1 Application Development Guide: Creating and Managing Sessions (Oracle GlassFish Server 3.0.1 Руководство по разработке приложений. Создание сеансов и управление ими).

Автоматическая обработка истечения времени ожидания сеанса

Если приложение основано на сеансах, необходимо принять меры для обеспечения простоты и удобства обработки ситуаций, когда поступает запрос для сеанса, время ожидания которого истекло или который невозможно определить. Это можно выполнить в проекте AffableBean, создав простой фильтр, перехватывающий заголовки запросов в файле ControllerServlet. Фильтр проверяет факт существования сеанса; если сеанс не существует, он перенаправляет запрос на страницу приветствия сайта.

  1. Начните работу с изучения проблемы, возникающей при истечении времени ожидания сеанса до его завершения из-за посещения сайта пользователем. Временно установите для времени ожидания сеанса значение в 1 минуту. Откройте дескриптор развертывания веб-приложения (web.xml) и введите значение "1" между тегами <session-timeout>.
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
  2. Запустите проект AffableBean. Щелкните на странице категорий в браузере, добавьте несколько элементов в корзину и щелкните ссылку "view cart".
    На странице корзины отображаются элементы в покупательской корзине
  3. Подождите минимум 1 минуту.
  4. Обновите количество для одного из товаров на странице корзины. (Допустимо любое число от 1 до 99.) Нажмите кнопку "update". Сервер отправит сообщение со статусом HTTP "500".
    Отчет об ошибке GlassFish отображается в браузере
  5. Изучите журнал сервера GlassFish в среде IDE. Откройте окно вывода (Ctrl-4; ⌘-4 в Mac) и перейдите на вкладку 'Сервер GlassFish'. Прокрутите до конца журнала для изучения трассировки стека ошибок.
    Отчет об ошибке GlassFish отображается в браузере
    Журнал сервера показывает, что исключение NullPointerException возникло в строке 184 ControllerServlet. В диалоговом окне "Вывод" появляется ссылка на строку, в которой возникло исключение.
  6. Щелкните ссылку. Вы попадете прямо на строку 184 в ControllerServlet. При наведении курсора мыши на значок ошибки в левом поле редактора выводится всплывающая подсказка с описанием исключения.
    Метка ошибки и подсказка отображаются в редакторе
    Поскольку время ожидания сеанса истекло до получения запроса, механизму сервлета не удалось связать запрос с соответствующим сеансом. Таким образом, оказалось невозможным обнаружить объект cart (строка 151). В конце концов, исключение произойдет на строке 184, когда попытка вызова метода по переменной, имеющей значение null.

    Проблема определена, для ее исправления необходимо реализовать фильтр.
  7. Нажмите кнопку 'Создать файл' (Кнопка 'Создать файл') на панели инструментов IDE. (В качестве альтернативы нажмите Ctrl-N; ⌘-N в Mac.)
  8. Выберите категорию "Веб", затем выберите "Фильтр" и нажмите кнопку "Далее".
  9. Присвойте фильтру имя SessionTimeoutFilter. Введите текст filter в поле "Пакеты" для размещения класса фильтра в новом пакете при его создании.
  10. Нажмите кнопку "Далее". Примите настройки по умолчанию и нажмите кнопку "Готово". Для фильтра SessionTimeoutFilter создается и открывается в редакторе шаблон.

    Примечание. В настоящее время в NetBeans 6.9 не поддерживается использование мастера для задания сопоставления с сервлетом, которые не зарегистрирован в дескрипторе веб-развертывания. (ControllerServlet был зарегистрирован с помощью аннотации @WebServlet). Следовательно, необходимо изменить созданный код в следующем шаге.

  11. Измените подпись аннотации @WebFilter следующим образом:
    @WebFilter(servletNames = {"Controller"})
    public class SessionTimeoutFilter implements Filter {
    Фильтр с такими настройками будет перехватывать любой запрос, который управляется ControllerServlet. (Также можно сохранить атрибут urlPatterns и перечислить все шаблоны, обрабатываемые в файле ControllerServlet.)

    Обратите внимание, что Controller является именем файла ControllerServlet, как указано в подписи аннотации @WebServlet сервлета. Заметим также, что атрибут filterName был удален, поскольку имя класса фильтра используется по умолчанию.

    Шаблон фильтра среды IDE предоставляет множество примеров кода, которые рекомендуется изучить. Однако большая часть кода не потребуется для целей этого упражнения. Любой класс фильтра должен реализовывать интерфейс Filter, определяющий три метода.
    • init: выполняет действия после инициализации фильтра, но до его размещения в службе.
    • destroy: удаляет фильтр из службы. Этот метод может быть также использован для выполнения операций очистки.
    • doFilter: используется для выполнения операций для каждого запроса, перехваченного фильтром.

    Используйте функцию поиска документации по индексу, чтобы вытянуть документацию по интерфейсу Filter. Нажмите сочетание клавиш SHIFT+F1 (fn+SHIFT+F1 в системе Mac), введите текст Filter в поле поиска и нажмите ENTER. Выберите запись "Interface in javax.servlet". Документация Javadoc выводится на нижней панели средства поиска по индексу.

  12. Замените тело фильтра SessionTimeoutFilter на следующее содержимое.
    @WebFilter(servletNames = {"Controller"})
    public class SessionTimeoutFilter implements Filter {
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
    
            HttpServletRequest req = (HttpServletRequest) request;
    
            HttpSession session = req.getSession(false);
    
            // if session doesn't exist, forward user to welcome page
            if (session == null) {
                try {
                    req.getRequestDispatcher("/index.jsp").forward(request, response);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                return;
            }
    
            chain.doFilter(request, response);
        }
    
        public void init(FilterConfig filterConfig) throws ServletException {}
    
        public void destroy() {}
    
    }
  13. Нажмите Ctrl-Shift-I (⌘-Shift-I в Mac) для исправления операторов импорта. (Необходимо добавить импорт для HttpServletRequest и HttpSession.) Используйте подсказки редактора чтобы добавить аннотацию @Override к методам init, destroy и doFilter.

    В следующих шагах выполняется запуск отладчика для проекта и переход по методу doFilter для просмотра способа определения привязки запроса существующему сеансу.
  14. Откройте окно точек останова (ALT+SHIFT+5; CTRL+SHIFT+5 в Mac OS) и удостоверьтесь, что не установлена ни одна точка останова. Для удаления точки останова щелкните правой кнопкой мыши точку останова и выбериет 'Удалить'. (Если было выполнено упражнение выше, Examining Client-Server Communication with the HTTP Monitor (Проверка соединения клиент-сервер с помощью HTTP-монитора), в ControllerServlet может быть установлена лишняя точка останова).
  15. Запустите отладчик. Нажмите кнопку 'Отладка проекта' (Кнопка 'Отладка проекта') на главной панели инструментов IDE.
  16. При выводе страницы приветствия в браузере выберите категорию и добавьте несколько элементов в корзину покупок.
  17. Установите точку останова на строку принадлежащего фильтру SessionTimeoutFilter метода doFilter, который пытается получить доступ к сеансу (строка 32).
    Точка останова задана в редакторе
  18. Щелкните в браузере ссылку "view cart". Перейдите к среде IDE и обратите внимание, что отладчик приостановил работу в точке останова.

    Учтите, что метод getSession() создает новый объект сеанса, если текущий объект не существует. В данном случае используется метод getSession(false), который не создает новый объект, если объект не найден. Другими словами, метод возвращает значение null, если сеанс не существует.
  19. Нажмите кнопку 'Обход процедур' ( Кнопка 'Обход процедур' ), затем подведите курсор мыши к переменной session. При условии, что с момента отправки предыдущего запроса не прошла минута, переменная присваивается типу StandardSessionFacade. Он представляет объект сеанса для запроса.
    Во всплывающем окне отображается переменная 'session', назначенная объекту сеанса
  20. Продолжайте двигаться по строкам метода, пока запрос не будет обработан. Поскольку переменная session не равна null, можно пропустить выражение if, и фильтр chain.doFilter направит запрос прямо к ControllerServlet (строка 44).
  21. Перейдите в браузер, убедитесь, что прошла минута, и обновите количество для одного из элементов продукта в корзине. Это та же самая процедура, которая выполнялась ранее в упражнении с возвратом сообщения 500. Выясним, что происходит при истечении времени ожидания сеанса теперь, когда фильтр перехватывает заголовки запросов для файла ControllerServlet.
  22. После щелчка элемента "Обновить" перейдите в среду IDE и обратите внимание, что отладчик снова приостановился на точке останова, установленной в фильтре.
  23. Выделите выражение req.getSession(false) и наведите на него курсор мыши. Обратите внимание, что выражение имеет значение null, поскольку время ожидания сеанса истекло.
    Во всплывающем окне отображается переменная 'session' со значением 'null'
  24. Продолжите переход по коду. Теперь переменная session равна null, выражение if на странице 35 обрабатывается, и запрос направляется прямо к /index.jsp. Когда отладчик завершает работу, в браузере выводится страница приветствия сайта.
  25. Нажмите кнопку 'Завершить сеанс' ( Кнопка 'Завершить сеанс' ), чтобы завершить сеанс отладки.
  26. Откройте файл web.xml проекта и снова измените время ожидания сеанса на 10 минут.
    <session-config>
        <session-timeout>10</session-timeout>
    </session-config>
  27. Сохраните файл (Ctrl-S; ⌘-S в Mac).

Снимок 6 демонстрирует полную версию проекта для данного раздела руководства. Рассмотрим еще один вопрос, касающийся управления сеансом. Можно завершить сеанс явным образом, вызвав метод invalidate для объекта сеанса. Если сеанс больше не требуется, необходимо удалить его для сохранения доступной памяти на сервере. После завершения следующего раздела, Интеграция транзакционной бизнес-логики, можно увидеть, как ControllerServlet после успешной обработки заказ клиента, уничтожает пользовательский объект cart и прерывает сессию, используя метод invalidate.

// if order processed successfully send user to confirmation page
if (orderId != 0) {

    // dissociate shopping cart from session
    cart = null;

    // end session
    session.invalidate();

    ...
}

Это демонстрируется в проектный снимок 8 (и следующих снимках).


Дополнительные сведения

Материалы по NetBeans

Ресурсы по GlassFish

Технические статьи и различные ресурсы

get support for the NetBeans

Support


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2018, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo