- •Обозначения и сокращения
- •введение
- •1. Установка и настройка инструментальных средств
- •1.1. Установка и подготовка к работе операционной системы
- •1.2. Установка программного обеспечения
- •1.3. Создание таблиц в базе данных
- •2. Основы Java EE 6
- •2.1. Распределенные многоуровневые приложения
- •2.2. Контейнеры Java EE
- •2.3. Сервер GlassFish v3
- •2.4. Структура приложения
- •2.5. Конфигурирование приложений
- •2.6. Задание ссылок на ресурсы
- •4. Введение в компоненты Facelets
- •4.1. Веб-страницы
- •4.2. Разработка простого приложения Facelets
- •4.3. Использование шаблонов
- •5. Унифицированный язык записи выражений
- •6.1. Добавление компонент библиотеки HTML на страницу
- •6.2. Использование компонент для таблиц баз данных
- •6.3. Использование тегов библиотеки Core
- •7. Использование конвертеров, слушателей и проверок
- •7.1. Использование стандартных преобразователей
- •7.2. Регистрация слушателей для компонентов
- •8. Внешние объекты (JavaBeans)
- •8.1. Создание класса внешних объектов
- •8.2. Описание свойств бинов
- •8.3. Написание методов внешних бинов
- •8.4. Проверка бинами
- •9.1. Файл конфигурации ресурсов приложения
- •9.2. Упорядочение ресурсов конфигурации приложения
- •9.3. Конфигурирование состояния проекта
- •9.4. Выбор конфигурации бина
- •9.5. Регистрация сообщений об ошибках как пакет ресурса
- •9.7. Конфигурирование правил навигации (Navigation Rules)
- •9.8. Основные требования приложения JavaServer Faces
- •10. Технология Java Servlet
- •11. Введение в Java Persistence API
- •11.1. Требования к классам сущностей
- •11.3. Внедряемые классы в сущностях
- •11.4. Наследование сущностей
- •11.5. Стратегии наследования сущностей с отображением
- •11.6. Управление сущностями
- •11.7. Запросы сущностей
- •12. Примеры хранимых сущностей
- •12.1. Приложение order
- •12.2. Пример получения схемы отношений на основе таблиц БД
- •13.1. Терминология языка запросов
- •13.3. Упрощенный синтаксис языка запросов
- •13.4. Примеры запросов
- •13.5. Запросы с навигацией связанных сущностей
- •13.6. Запросы с другими условными выражениями
- •13.7. Изменение и удаление группы сущностей
- •13.8. Полный синтаксис языка запросов
- •14. Язык запросов Criteria API
- •14.3. Корни запроса
- •14.4. Использование объединения в запросе
- •14.5. Навигация путей в запросах
- •14.6. Ограничения на результаты запроса
- •14.7. Управление результатами запросов
- •14.8. Исполнение запросов
- •15. Связывание ресурсов
- •15.1. Ресурсы и служба имен JNDI
- •15.2. Объекты DataSource и пулы соединений (Connection Pools)
- •15.3. Внедрение ресурсов
- •15.4. Адаптеры ресурсов
- •15.5. Аннотации метаданных
- •16. Безопасность веб-приложений
- •16.1. Краткий обзор
- •16.2. Механизмы обеспечения безопасности
- •16.3. Безопасность сервера предприятия
- •16.4. Использование защищенного соединения SSL
- •18. Пример приложения
- •18.1. Создание проекта веб-приложения
- •18.3.Структура приложения JavaEE 6
- •18.4. Программирование вида для объектов
- •18.5. Дизайн главной страницы
- •18.6. Страница просмотра записей таблицы городов
- •18.7. Страница добавления записей о городах
- •18.8. Страница редактирования записей о городах
- •18.9. Страница удаления записей о городах
- •19. Обработка связей внешних ключей
- •19.1. Разработка класса для вида сущности
- •19.2. Доработка вида для городов
- •19.3. Разработка обзорной страницы
- •19.5. Страница для редактирования записей с внешними ключами
- •20. Дополнительные функции
- •20.1. Сортировка записей таблицы
- •20.2. Контроль за удалением связанных записей
- •20.3. Контроль ввода наименований
- •20.4. Запросы к БД на языке Java Persistence Query Language
- •20.5. Управление страницами при просмотре таблицы
- •20.6. Создание и просмотр отчетов
- •20.7. Использование шаблонов и стилей
- •20.8. Защита приложения паролем
- •Заключение
- •Библиографический список
10. Технология Java Servlet
Особенностью веб-приложений является динамическое формирование стра-
ниц, отправляемых клиенту в ответ на его запросы. Предназначение технологии Java
Servlet — создание динамического содержимого с использованием программирования
только на языке Java. Вследствие этого технология Java Servlet используется в при-
кладном программировании крайне редко, поскольку технология JavaServer Faces предоставляет значительный объем сервисов и инструментов для эффективной раз-
работки веб-приложений. Однако при разработке серверов со специальными требо-
ваниями к скорости, защите данных, к функциональности и другими технология позво-
ляет проконтролировать указанные моменты более тщательно.
Сервлет является классом языка Java, используемым для расширения функциональных возможностей веб-серверов, на которых размещаются приложения, доступ
к которым осуществляется посредством программной модели «запрос – ответ». Для
таких приложений технология Java Servlet предлагает специальные классы.
Пакеты javax.servlet и javax.servlet.http обеспечивают интерфейсы и классы для
написания сервлетов. Все сервлеты должны реализовывать интерфейс Servlet, который определяет методы жизненного цикла экземпляра класса. Дополнительно при
реализации службы generic можно использовать или расширять класс GenericServlet.
Класс HttpServlet обеспечивает для служб HTTP такие методы, как doGet и doPost.
Жизненный цикл сервлета управляется контейнером, в котором был размещен сервлет. При направлении запроса сервлету контейнер выполняет следующие действия:
1.Если экземпляр сервлета не создан, то:
а) загружает класс сервлета;
б) создает экземпляр класса сервлета;
в) инициализирует экземпляр сервлета путем вызова метода init.
2.Вызывает метод service, передавая ему объекты запроса и ответа.
Если контейнеру необходимо удалить сервлет, он завершает работу сервлета
путем вызова его метода destroy.
Отслеживать и реагировать на события жизненного цикла сервлетов можно путем определения объектов-слушателей (табл. 10.1). Когда в жизненном цикле сервлета происходит событие, вызываются методы соответствующих объектов-слушателей. Для их использования необходимо определить класс-слушатель. При вызове метода
слушателя ему передается событие, содержащее информацию, соответствующую
данному событию. К примеру, методам в интерфейсе HttpSessionListener передаются
события класса HttpSessionEvent, содержащие объект класса HttpSession.
При работе сервлета возможно появление некоторых ошибок. В случае ошибки
веб-контейнер создает страницу, определённую по умолчанию, в которой содержит-
ся сообщение “A Servlet Exception Has Occurred”. Однако вы можете задать, чтобы контейнер возвращал специальную страницу ошибок для конкретной исключительной
ситуации. Для определения такой страницы добавьте элемент error-page в дескриптор
размещения веб-приложения.
Веб-компоненты для выполнения своих задач часто используют другие объекты. Для этого существует несколько способов. Можно использовать частные вспомога-
тельные объекты (например, JavaBean-компоненты) или же совместно использовать
объекты, являющиеся атрибутами области действия public. Веб-компоненты могут
также использовать базу данных и другие веб-ресурсы.
106
Взаимодействующие веб-компоненты передают общую информацию через
атрибуты объектов четырех областей действия. Доступ к этим атрибутам производится при помощи методов [get|set]<Attribute> для объекта, представляющего соответствую-
щую область действия. В табл. 10.2 перечислены объекты и области их действия.
|
|
Таблица 10.1 |
|
События жизненного цикла сервлетов |
|
|
|
|
Объект |
Событие |
Интерфейс слушателя и класс события |
Web context |
Инициализация |
Javax.servlet.ServletContextListener |
|
и разрушение |
и ServletContextEvent |
|
Добавление, удаление |
Javax.servlet.ServletContextAttributeListener |
|
или замена атрибута |
и ServletContextAttributeEvent |
Session |
Создание, аннулирова- |
javax.servlet.http.HttpSessionListener |
|
ние и тайм-аут |
и HttpSessionEvent |
|
|
|
Request |
Добавление, удаление |
javax.servlet.http.HttpSessionAttributeListener |
|
или заменена атрибута |
и HttpSessionBindingEvent |
|
Старт запроса |
javax.servlet.ServletRequestListener |
|
|
и ServletRequestEvent |
|
Добавление, удаление |
javax.servlet.ServletRequestAttributeListener |
|
или замена атрибута |
и ServletRequestAttributeEvent |
|
|
Таблица 10.2 |
|
|
Объекты и области действия |
||
|
|
|
|
Объект области |
Класс |
Откуда доступен |
|
действия |
|||
|
|
||
Web context |
javax.servlet.ServletContext |
Компонент внутри контекста |
|
Session |
javax.servlet.http.HttpSession |
Компоненты, обрабатывающие |
|
|
|
запрос, относящийся к сессии |
|
Request |
Подтип javax.servlet.ServletRequest |
Компоненты, обрабатывающие |
|
|
|
запрос |
|
Page |
javax.servlet.jsp.JspContext |
Jsp-страница, создавшая объект |
В многопоточном сервере возможен совместный доступ к общим ресурсам. Кроме атрибутов объекта области действия, общие ресурсы включают в себя данные, находящиеся в памяти, такие как переменная экземпляра или переменные класса,
а также внешние объекты, такие как файлы, соединения с базами данных и сетевые
соединения. Совместный доступ может осуществляться в различных ситуациях:
•множество веб-компонентов, получающих доступ к объектам, хранящимся в
веб-контексте;
•множество веб-компонентов, получающих доступ к объектам, хранящимся в
сессии;
•множество потоков внутри веб-компонента, получающих доступ к перемен-
ным экземпляров.
Веб-контейнер обычно создает поток для обработки каждого запроса. Для гарантии того, что экземпляр сервлета обрабатывает одновременно только один запрос,
сервлет может реализовывать интерфейс SingleThreadModel. Если сервлет реализу-
107
ет данный интерфейс, то гарантируется, что в методе сервлета одновременно будет
выполняться не более одного потока. В веб-контейнере это реализуется путем синхронизации доступа к отдельному экземпляру сервлета или путем поддержания пула
экземпляров веб-компонентов и перенаправления каждого нового запроса к свобод-
ному экземпляру. Данный интерфейс не ограждает от проблем, связанных с синхрони-
зацией, которые возникают в результате доступа веб-компонентов к общим ресурсам,
таким как статические переменные класса или внешние объекты.
Данные, которые являются общими для веб-компонентов и сохраняются между
вызовами веб-приложения, обычно содержатся в базах данных. Веб-компоненты ис-
пользуют технологию Java Persistence API для доступа к реляционным базам данных.
Веб-контейнер инициализирует сервлет после того, как он загружает и создает
экземпляр класса сервлета, перед передачей ему запросов от клиентов. Вы можете самостоятельно настроить данный процесс, позволив сервлету считывать постоян-
ные данные конфигурации, а также инициализировать ресурсы и обеспечивать любые
другие единовременные действия путем перекрытия метода init интерфейса Servlet.
Сервлет, который не в состоянии завершить процесс инициализации, должен возбуж-
дать ошибку UnavailableException.
Функциональность, обеспеченная сервлетом, помещается в методе service
сервлета GenericServlet, в методах с именами do<Method> (где Method может прини-
мать значения Get, Delete, Options, Post, Put, Trace) сервлета HttpServlet или любых
других определённых протоколом методов, которые определены в классе, реализую-
щих интерфейс Servlet. Общим алгоритмом работы метода do... является извлечение информации из запроса, доступ к внешним ресурсам и последующее заполнение ответа на основе данной информации.
Для сервлетов HTTP правильной последовательностью заполнения ответа бу-
дет: заполнение заголовков ответа, получение входящего потока из генератора ответа
и запись содержимого страницы в исходящий поток. Заголовки ответов всегда должны устанавливаться перед получением PrintWriter или ServletOutputStream. Это необходимо по причине того, что HTTP-протокол ожидает получения всех заголовков перед получением содержимого тела.
Запрос содержит данные, передаваемые от клиента к сервлету. Все объекты-
запросы реализуют интерфейс ServletRequest. Данный интерфейс определяет методы для доступа к следующей информации:
•параметры, используемые для передачи информации от клиента к сервлету;
•объекты-атрибуты, которые обычно используются для передачи информации
между контейнером сервлета и сервлетом, или между взаимодействующими сервлетами;
•протокол, использованный для соединения, а также сведения о клиенте и сервере, которые вовлечены в запрос;
•информация, относящаяся к локализации (страна и особенности представления денег и даты).
Входящий поток можно также получать из запроса, а затем вручную обраба-
тывать данные. Для чтения символьных данных необходимо использовать объект
BufferedReader, возвращаемый методом экземпляра запроса getReader. Для чтения бинарных данных используется ServletInputStream, возвращаемый методом getInputStream.
HTTP-сервлету передается объект запроса HTTP HttpServletRequest, содержа-
щий URL запроса, HTTP-заголовки, строку запроса и т. д. URL запроса HTTP состоит из следующих частей: http://[host]:[port][request path]?[query string]
108
Путь запроса, в свою очередь, состоит из следующих элементов:
•путьконтекста:сочетаниезнака«слеш»(/)скорнемконтекставеб-приложения
сервлета;
•путь сервлета: участок пути, соответствующий псевдониму компонента, кото-
рый активирует данный запрос. Этот участок начинается со знака «слеш» (/);
•информация о пути: участок пути запроса, не являющийся частью пути контекста или пути сервлета.
Строки запросов состоят из набора параметров и их значений. Отдельные па-
раметры получают из запроса при помощи метода getParameter. Существует два способа создания строк запроса:
1)строка запроса может появляться явным образом в веб-странице. К примеру,
HTML-страница, созданная сервлетом Catalog, может содержать ссылку
<a href="/bookstore1/catalog?Add=101">Add To Cart</a>
Тогда сервлет Catalog извлекает параметр с именем Add следующим образом:
String bookId = request.getParameter("Add");
2)строка запроса добавляется к URL при отправке данных формы при исполь-
зовании метода GET протокола HTTP и извлекается сервлетом при помощи
метода getParameter.
Ответ содержит данные, передаваемые от сервера клиенту. Все ответы реализуют интерфейс ServletResponse. Данный интерфейс определяет методы, которые позволяют выполнять следующие действия:
1.Получать исходящий поток данных, предназначенных для отправки клиенту.
Для отправки данных в текстовом виде используется PrintWriter, возвращаемыйметодомgetWriter классаServletResponse.Дляотправкибинарныхданных в теле MIME ответа используется объект ServletOutputStream, возвращаемый методом getOutputStream. Для совмещения бинарных и текстовых данных, к
примеру, при создании ответа, состоящего из нескольких частей, используется
ServletOutputStream для управления секциями символов вручную.
2.Обозначать тип содержимого (к примеру, text/html), возвращаемого в данном ответе. Реестр имен типов содержимого организации IANA (Internet Assigned Numbers Authority — Агентство по выделению имен и уникальных параме-
тров протоколов Интернета) хранится по адресу: ftp://ftp.isi.edu/in-notes/iana/ assignments/media-types.
3.Указывать, осуществляется ли вывод в буфер методом setBufferSize(int). По умолчанию любое содержимое, записываемое в исходящий поток, немед-
ленно отправляется клиенту. Буферизация позволяет записывать содержи-
мое перед отправкой клиенту. Таким образом, сервлету предоставляется
больше времени для установки соответствующих кодов статуса и заголов-
ков, а также для переназначения содержимого другому веб-ресурсу.
4.Устанавливать информацию о регионе.
Объекты HTTP-ответа HttpServletResponse имеют поля, отображающие такие
заголовки HTTP, как:
•коды статуса (Status codes), используются для обозначения причины, по кото-
рой не был удовлетворен запрос;
•файлы сookie (Cookies), используются для сохранения у клиента информации, связанной с приложением. Иногда файлы cookie используются для сохранения идентификатора сессии пользователя.
109
Многие приложения требуют, чтобы последовательные запросы клиента были связаны некоторым контекстом. Для того чтобы осуществлять поддержку приложений,
требующих сохранения своего состояния, технология Java Servlet обеспечивает спе-
циальный инструмент для управления сессиями.
Сессии представляются при помощи объекта класса HttpSession. Доступ к сес-
сии можно получить, вызывая метод getSession объекта запроса. Данный метод возвращает текущую сессию, ассоциированную с запросом, или, если у запроса нет сес-
сии, он создает ее. Так как метод getSession может изменить заголовок запроса (если
файлы cookie являются механизмом для отслеживания сессии), необходимо вызвать
его до того, как вы извлечете PrintWriter или ServletOutputStream.
Вы можете ассоциировать объектно-значимые атрибуты с сессией при помощи
имен атрибутов. Доступ к таким атрибутам может получить любой веб-компонент, при-
надлежащий к тому же веб-контексту, и обрабатывающий запрос, являющийся частью той же сессии.
У HTTP-клиента нет возможности сообщить об отсутствии потребности в сес-
сии. По этой причине для каждой сессии существует определённый лимит време-
ни существования, а ее ресурсы можно при необходимости востребовать повтор-
но. Доступ к значению этого времени можно получить при помощи методов [get|set]
MaxInactiveInterval сессии. Его также можно установить в файлах конфигурации.
Для того чтобы временной лимит сессии не истек, следует периодически осу-
ществлять к ней доступ посредством методов служб. Этот доступ обнуляет значение
счетчика времени. После завершения определённых взаимодействий клиента используйте метод сессии invalidate. Он позволяет «отключить» сессию на стороне сервера и удалить все сессионные данные.
Веб-контейнер может использовать некоторые методы для связывания сессии
с пользователем, каждый из которых включает передачу идентификатора между кли-
ентом и сервером. Можно сохранять идентификатор на стороне клиента как cookieфайл; или же веб-компонент может включить требуемый идентификатор в каждый URL-адрес, возвращаемый клиенту.
Если ваше приложение использует сессионные объекты, необходимо настроить
его таким образом, чтобы при каждом отключении функции сохранения cookie-файлов
URL-адреса перезаписывались. При этом гарантируется способность отслеживания сессии. Это осуществляется при помощи вызова метода ответа encodeURL(URL) во всех URL-адресах, возвращаемых сервлетом. Данный метод включает сессионный ID в URL-адрес только в том случае, если cookie-файлы отключены. В противном случае он возвращает URL неизмененным.
Когда контейнер сервлета определяет, что сервлет должен быть удален из служ-
бы (например, при необходимости восстановить ресурсы памяти или при завершении
работы), он вызывает метод destroy интерфейса Servlet. В данном методе освобож-
даются все ресурсы, используемые сервлетом, и сохраняется постоянное состояние.
При удалении сервлета все его методы служб должны быть завершены. Сервер попытается проверить это, вызвав метод destroy после возврата всех запросов служб или
же после заданного сервером периода отсрочки, в зависимости от того, что наступит
первым. Если ваш сервлет выполняет операции, занимающие большое количество
времени (то есть, операции, которые протекают дольше периода отсрочки сервера), при вызове метода destroy данные операции могут все еще выполняться. Вы должны удостовериться, что все потоки, обрабатывающие запросы клиентов, завершены.
110