
- •Обозначения и сокращения
- •введение
- •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. Защита приложения паролем
- •Заключение
- •Библиографический список
8.3. Написание методов внешних бинов
Методы внешнего бина могут выполнить несколько специализированных функций для компонентов на странице. Эти функции включают:
выполнение проверки вводимых в компонент значений;обработка событий действия;
обработка событий изменения значений;
выполнение навигации.
Использование внешних бинов для выполнения этих функций устраняет необ-
ходимость реализовывать интерфейс Validator, чтобы выполнять проверку данных,
или интерфейс Listener, чтобы обрабатывать события. Используя внешний бин вместо реализации Validator, вы устраняете необходимость создавать собственный тег для
реализации проверок.
Методам нужно иметь доступ к данным компонента, чтобы обрабатывать со-
бытие или выполнять проверку связанных с бином данных компонента. Поэтому эти
методы полезно включать в тот же внешний бин, который определяет свойства для компонентов, ссылаясь на его методы.
8.3.1. Методы для навигации
Метод бина для выполнения навигации, вызываемый методом action, дол-
жен быть методом public, который не имеет параметров и возвращает данные типа Object — логический результат, который использует система навигации, чтобы определить следующую отображаемую страницу. На этот метод ссылается атрибут action тега компонента.
Следующий метод action внешнего бина с именем CashierBean вызывается,
когда пользователь щелкает кнопку Submit на странице. Если пользователь заказал книги на сумму более чем $100, этот метод заменяют свойства rendered и specialOffer компонентов fanClub на true, чтобы они отображались на странице в следующий раз при её генерации.
После установки свойства компонентов в true этот метод возвращает логиче-
ский результат null. Это заставляет реализацию JavaServer Faces при перерисовке страницы не создавать новый вид страницы, сохранив ввод пользователя. Если этот метод должен возвращать логический результат, чтобы использовать его для навигации на страницу оплаты, страница будет регенерироваться без сохранения пользо-
вательского ввода.
Еслипользовательнеприобретаеткнигистоимостьюболеечем$100иликомпо-
нент thankYou уже был сгенерирован, то метод возвращает строку receipt. JavaServer
Faces загружает страницу после того, как этот метод закончится.
public String submit() { // Метод для обработки нажатия кнопки
...
if(cart().getTotal() > 100.00 && !specialOffer.isRendered())
{
specialOfferText.setRendered(true);
specialOffer.setRendered(true); return null;
} else
if (specialOffer.isRendered() && !thankYou.isRendered())
{
82
thankYou.setRendered(true); return null;
} else
{
clear();
return ("receipt");
}
}
Обычно метод обработки действия возвращает результат-строку, как показано в предшествующем примере. Кроме того, вы можете определить класс Enum, который
хранит все возможные строки-результаты, затем возвращает методом действия константы enum, которые представляют конкретный результат типа String, определённый классом Enum. В этом случае возвращаемое вызовом метода toString класса Enum значение результата должно соответствовать элементу from правил навигации в файле конфигурации приложения.
Следующий пример использует класс Enum, чтобы включить строки всех логических результатов:
public enum Navigation {
main, accountHist, accountList, atm, atmAck, transferFunds, transferAck, error
}
Когда метод возвращает результат, он использует точечную нотацию, чтобы
ссылаться на элемент из класса Enum: public Object submit(){
...
return Navigation.accountHist;
}
8.3.2. Методы для обработки событий Action
Метод внешнего бина для обработки событий должен быть методом public, ко-
торый принимает событие и возвращает void. На этот метод указывает ссылка в атри-
буте actionListener тега компонентов. Только компоненты, которые реализуют интерфейс ActionSource, могут ссылаться на этот метод.
В следующем примере метод из внешнего бина LocaleBean обрабатывает со-
бытие пользователя, щелкающего по одной из гиперссылок на странице:
public void chooseLocaleFromLink(ActionEvent event) { // Получить ID того, кто вызвал
String current = event.getComponent().getId(); // контекст
FacesContext context = FacesContext.getCurrentInstance(); context.getViewRoot().setLocale((Locale)
locales.get(current)); // локаль
}
Этот метод ищет компонент, который генерировал событие из параметра event,
а затем он получает ID компонента, который указывает регион мира. Метод ищет ID
в объекте locales класса HashMap, который содержит доступные локали для прило-
83
жения. Далее он устанавливает локаль действия, используя выбранное значение из объекта HashMap.
8.3.3. Методы для выполнения проверки (Validation)
Вместо реализации интерфейса Validator, чтобы выполнять проверки данных для компонента, вы можете включить метод во внешний бин. Метод внешнего
бина, который выполняет проверку, должен иметь три параметра: компонент класса
FacesContext, компонент, чьи данные должны быть проверены, и сами данные, которые нужно проверить, подобно тому, как это делает метод интерфейса Validator.
Компонент ссылается на метод внешнего бина, используя атрибут validator. Могут
быть проверены значения только компонентов Input или их потомков. Пример метода внешнего бина, который проверяет ввод пользователя:
public void validateEmail(FacesContext context, UIComponent toValidate, Object value) { String message = "";
String email = (String) value;
if (! email.contains(’@’)) { // Если ошибка ввода ((UIInput)toValidate).setValid(false);
message = CoffeeBreakBean.loadErrorMessage(context, CoffeeBreakBean.CB_RESOURCE_BUNDLE_NAME, "EMailError");
context.addMessage(toValidate.getClientId(context), new FacesMessage(message));
}
}
Давайте более внимательно посмотрим на вышеуказанный сегмент кода:
1.Метод validateEmail сначала получает локальное значение value.
2.Затем он проверяет, есть ли символ @ в value.
3.Если символа @ нет, то метод устанавливает свойство valid в false методом setValid.
4.Затем он загружает сообщение об ошибке и ставит его в очередь в экземпляр FacesContext, связывая сообщение с ID компонента, получаемым методом toValidate.getClientId(context).
8.3.4. Методы для обработки событий (Value Change)
Внешний бин, который обрабатывает события изменения значений, должен ис-
пользовать метод public, который принимает события и возвращает void. На этот ме-
тод ссылается атрибут valueChangeListener компонента.
Ниже показано, как написать метод внешнего бина, чтобы заменить реализа-
цию ValueChangeListener. Следующий пример тега h:inputText с id name содержит в себе тег ValueChangeListener. Экземпляр класса ValueChangeListener обрабатывает
событие ввода значения в поле соответствующего компонента. Когда пользователь
вводит значение, генерируется событие изменения значения и вызывается метод processValueChange(ValueChangeEvent) класса ValueChangeListener.
<h:inputText id="name" size="50" value="#{cashier.name}" required="true">
84
<f:valueChangeListener type="listeners.NameChanged" /> </h:inputText>
Взамен реализации ValueChangeListener вы можете написать метод внешнего
бина, чтобы обрабатывать это событие. Для того чтобы сделать это, нужно перенести
метод processValueChange(ValueChangeEvent) из класса ValueChangeListener с име-
нем NameChanged в класс внешнего бина:
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
if (null != event.getNewValue()) { FacesContext.getCurrentInstance().
getExternalContext().getSessionMap(). put(“name”, event.getNewValue());
}
}
Для того чтобы сделать этот метод обработчиком события ValueChangeEvent,
сгенерированного компонентом Input, сделайте ссылку на этот метод из атрибута valueChangeListener тега компонента, например: valueChangeListener="#{cashier.processValueChange}"
8.4. Проверка бинами
Инструментарий Bean Validation (JSR 303) является новой возможностью, которая
доступна в Java EE 6. Реализации JavaServer Faces 2.0 должны поддерживать биновую проверку, если это требуется во время работы сервера (как, например, Java EE 6).
Проверка может размещаться в других слоях в случае простейшего приложения, как по-
казано в примере приложения guessNumber. Приложение guessNumber проверяет ввод пользователя (в теге <h:inputText> ) для цифровых данных в слое представления, а для
правильного диапазона — в бизнес-слое.
Модель проверки бинами поддерживается за счет использования аннотаций, помещённых в поле ввода, методе или в классе компонента JavaBeans. Ограничения
могут быть встроенными или определены пользователем. Несколько встроенных ан-
нотаций доступны в пакете javax.validation.constraints. Некоторые часто используемые встроенные аннотации указаны ниже:
@Min: элемент должен быть числом, чьё значение должно быть более или равно заданному минимуму.
@Max: элемент должен быть числом, чьё значение должно быть меньше или равно определённому максимуму.
@Size: элемент должен быть в границах между определённым минимумом и
максимумом.
@NotNull: элемент не должен быть null. @Null: элемент должен быть null.
@Pattern: элемент должен соответствовать определённому регулярному выражению языка Java.
Полный список встроенных аннотаций находится в документации по API для класса javax.validation.constraints по адресу: http://java.sun.com/javaee/6/docs/api/.
85
В следующем примере ограничение установлено в поле использованием встроенной аннотации @NotNull:
public class Name {
@NotNull
private String firstname; @NotNull
private String lastname;
}
Вы можете также установить более чем одно ограничение на одном объекте
JavaBeans, например, дополнительное ограничение для размера области в имени и
фамилии:
public class Name {
@NotNull @Size(min=1, max=16)
private String firstname; @NotNull
@Size(min=1, max=16) private String lastname;
}
Следующий пример показывает заданное пользователем ограничение, уста-
новленное для проверки адреса email встроенным шаблоном в методе бина запроса адреса:
@validEmail
public String getEmailAddress() { return emailAddress;
}
Определённому пользователем ограничению также нужна реализация проверки. Для встроенных по умолчанию ограничений реализация всегда доступна.
Любые неудачи проверки прекрасно обрабатываются и могут быть отображены тегом h:messages.
86