
- •Обозначения и сокращения
- •введение
- •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. Защита приложения паролем
- •Заключение
- •Библиографический список
7. Использование конвертеров, слушателей и проверок
7.1.Использование стандартных преобразователей
Java Server Faces обеспечивает набор реализаций преобразователей, который выможетеиспользовать,чтобыпреобразовыватьданныедлякомпонент.Стандартные
преобразователи расположены в пакете javax.faces.convert. Среди них:
•
•
•
•
•
•
•
•
•
•
•
•
•
BigDecimalConverter,
BigIntegerConverter,
BooleanConverter,
ByteConverter,
CharacterConverter,
DateTimeConverter,
DoubleConverter,
EnumConverter,
FloatConverter,
IntegerConverter,
LongConverter,
NumberConverter,
ShortConverter.
С каждым из этих преобразователей связано стандартное сообщение об ошибках. Например, если BigIntegerConverter не может преобразовать значение, то отображается сообщение:
{0} must be a number consisting of one or more digits
В этом случае параметр подстановки {0} будет заменён именем компонента
ввода, на котором зарегистрирован преобразователь.
Два стандартных преобразователя (DateTimeConverter и NumberConverter) имеют свои собственные теги, которые позволяют задавать формат данных компонента с
использованием атрибутов тега.
7.1.1. Преобразование данных
Чтобы использовать конкретный преобразователь значений компонент, нужно
зарегистрировать его для компонента одним из следующих четырёх способов:
1)поместить один из стандартных преобразователей convertDateTime и convertNumber в тег компонента;
2)связать значение компонента со свойством бина такого же типа, как преобразователь;
3) сослаться на преобразователь в атрибуте converter тега компонента;
4)поместить тег преобразователя внутрь тега компонента и использовать атрибут converterId или binding , чтобы сослаться на преобразователь.
65
Пример второго способа: если нужно данные компонента преобразовывать в
целое, можно связать значение компонента со свойством внешнего бина.
Integer age = 0;
public Integer getAge(){ return age;}
public void setAge(Integer age) { this.age = age;}
Если компонент не связан со свойством бина, то можно применить третий спо-
соб, используя атрибут converter непосредственно в теге компонента:
<h:inputText converter="javax.faces.convert.IntegerConverter" />
Этот пример показывает атрибут преобразователя, указывающий полное имя класса преобразователя. Атрибут преобразователя может также получить ID компонента.
Данные из тега inputText в этом примере будут преобразованы в java.lang.Integer.
Тип Integer является предопределённым типом |
NumberConverter. Если |
вам не нужно определять инструкции форматирования, |
используя атрибуты тега |
convertNumber и если один из стандартных преобразователей достаточен, вы можете просто сослаться на этот преобразователь, используя атрибут converter компонента.
Если вы хотите использовать атрибут converterId или binding, чтобы сослаться на преобразователь, атрибут converterId должен ссылаться на ID преобразователя,
например:
<h:inputText value="#{LoginBean.Age}" /> <f:converter converterId="Integer" />
</h:inputText>
7.1.1.1. Использование DateTimeConverter
Вы можете преобразовать данные в тип Java.util.Date, вкладывая тег convertDateTime в тег компонента. Тег convertDateTime имеет несколько атрибутов, которые позволяют определять формат и тип данных. В табл. 7.1 перечислены атри-
буты тега convertDateTime.
|
|
Таблица 7.1 |
|
Атрибуты тега convertDateTime |
|
|
|
|
Атрибут |
Тип |
Описание |
binding |
DateTimeConverter |
Для связывания конвертера с бином |
dateStyle |
String |
Формат java.text.DateFormat части даты как строки. |
|
|
Применяется при отсутствии шаблона |
locale |
String or Locale |
Локальный формат даты. Если не задан, |
|
|
то используется FacesContext.getLocale |
pattern |
String |
Шаблон для преобразования даты. Если задан, |
|
|
то игнорируются атрибуты dateStyle, timeStyle и type |
timeStyle |
String |
Задание преобразования времени суток. |
|
|
Допускаются: default, short, medium, long и full |
timeZone |
String or TimeZone |
Задание зоны времени (часового пояса) |
type |
String |
Задаёт тип: дату, время или оба значения |
for |
String |
Используется с композитными компонентами, |
|
|
указывая на тег, для которого он определен |
66
Простой пример тега convertDateTime:
<h:outputText id= "shipDate" value="#{cashier.shipDate}"> <f:convertDateTime dateStyle="full" />
</h:outputText>
При встраивании преобразователя DateTime в компонент убедитесь, что свой-
ство внешнего бина, с которым компонент связан, имеет тип java.util.Date. В предыду-
щем примере свойство cashier.shipDate должно быть типа java.util.Date. Пример может
вернуть следующий текст:
Saturday, September 26, 2009
Вы можете также отобразить ту же дату и время, используя следующий тег с
определением формата даты:
<h:outputText value="#{cashier.shipDate}"> <f:convertDateTime
pattern="EEEEEEEE, MMM dd, yyyy" /> </h:outputText>
Если вы хотите отобразить дату по-испански, то можете использовать атрибут
места действия:
<h:inputText value="#{cashier.shipDate}"> <f:convertDateTime dateStyle="full" locale="Locale.SPAIN"
timeStyle="long" type="both" /> </h:inputText>
Этот тег должен отобразить следующий выход: sabado 26 de septiembre de 2009
7.1.1.2. Использование NumberConverter
Вы можете преобразовать данные в java.lang.Number, вкладывая тег convertNumber в тег компонента. Тег convertNumber имеет несколько атрибутов, кото-
рые позволяют определять формат и тип данных, приведённые в табл. 7.2.
|
|
Таблица 7.2 |
|
Атрибуты тега convertNumber |
|
|
|
|
Атрибут |
Тип |
Описание |
binding |
DateTimeConverter |
Для связывания конвертера с бином |
currencyCode |
String |
Код денег ISO 4217 |
currencySymbol |
String |
Символ денежных единиц |
groupingUsed |
boolean |
Группировать с использованием разделителя |
integerOnly |
boolean |
Формировать только целую часть числа |
locale |
String или Locale |
Задание локальной системы преобразований |
maxFractionDigits |
int |
Максимальное число цифр дробной части |
maxIntegerDigits |
int |
Максимальное число цифр целой части |
minFractionDigits |
int |
Минимальное число цифр дробной части |
minIntegerDigits |
int |
Минимальное число цифр целой части |
pattern |
String |
Шаблон форматирования |
type |
String |
Задаёт тип: числа, деньги или проценты (по |
|
|
умолчанию — числа) |
for |
String |
Используется с композитными компонентами, |
|
|
указывая на тег, для которого он определён |
67
Следующий пример использует тег convertNumber, чтобы разместить общую стоимость книг в корзине:
<h:outputText value="#{cart.total}" > <f:convertNumber type="currency"/>
</h:outputText>
При связывании преобразователя чисел с компонентом необходимо, чтобы тип свойствавнешнегобинабылjava.lang.Number.Впредыдущемпримеревыражениеcart. total должно быть типа java.lang.Number. Пример числа, отображаемого этим тегом:
$934
Этот результат может отображён следующим тегом, где определён валютный
шаблон:
<h:outputText id="cartTotal" value="#{cart.total}" > <f:convertNumber pattern=”$####”
/>
</h:outputText>
7.2. Регистрация слушателей для компонентов
Разработчик приложения может реализовать слушателей как классы или как методы бинов. Если слушатель является внешним методом, автор страницы ссылает-
ся на метод из атрибута valueChangeListener или actionListener. Если слушатель явля-
ется классом, автор может ссылаться на слушателя или из тега valueChangeListener, или из тега actionListener и вкладывать их в тег компонента, чтобы зарегистрировать слушателя для этого компонента.
7.2.1. Регистрация слушателей изменений значений
Реализация AValueChangeListener может быть зарегистрирована в компоненте,
который реализует EditableValueHolder, вкладывая тег valueChangeListener в целевой
тег на странице. Тег valueChangeListener поддерживает два атрибута:
•type: ссылка на подходящее имя класса реализации интерфейса
ValueChangeListener с методом void processValueChange(ValueChangeEvent event);
•binding: ссылка на объект, который реализует интерфейс
ValueChangeListener.
Один из этих атрибутов должен быть использован для указания слушателя из-
менения значения. Атрибут типа может быть литералом или выражением. Атрибут
связи может быть только выражением, которое должно указать на свойство внешнего
бина, которое хранит и возвращает реализацию ValueChangeListener.
Следующий пример показывает слушателя изменений, зарегистрированного в
компоненте:
<h:inputText id="name" size="50" value="#{cashier.name}" required="true">
<f:valueChangeListener type="listeners.NameChanged" /> </h:inputText>
68
В данном примере атрибут type определяет слушателя NameChanged как реализацию интерфейса ValueChangeListener, который зарегистрирован для свойства name объекта cashier. После того как тег компонента будет обработан и локальные
данные от клиента будут проверены, соответствующий компонент поставится в оче-
редь ValueChangeEvent, который связан со слушателем событий ValueChangeListener
для компонента.
Атрибут связывания используется, чтобы связывать реализацию
ValueChangeListener со свойством внешнего бина. Это работает аналогично атрибуту
связывания, поддерживаемого стандартными тегами преобразователя.
7.2.2. Регистрация слушателей для операций
Автор приложения может зарегистрировать реализацию ActionListener в компоненте Command, вкладывая тег actionListener внутрь командного тега. Аналогично
тегу valueChangeListener, тег actionListener поддерживает как атрибуты type и binding.
Должен быть использован один из этих атрибутов, чтобы ссылаться на слушателя
действия. Пример тега commandLink с использованием класса реализации интер-
фейса ActionListener, а не метода внешнего бина:
<h:commandLink id="NAmerica" action="bookstore"> <f:actionListener type="listeners.LocaleChange" />
</h:commandLink>
Атрибут type тега actionListener задаёт полное имя класса реализации
ActionListener. Аналогично тегу valueChangeListener, тег actionListener также поддер-
живает атрибут binding.
7.2.3. Использование стандартных проверок (Standard Validators)
JavaServer Faces обеспечивает набор стандартных классов и связанных тегов,
которые авторы страниц и разработчики приложений могут использовать, чтобы проверять данные от компонент. В табл. 7.3 показаны все стандартные классы проверок и теги, которые позволяют использовать проверки на страницах.
|
|
Таблица 7.3 |
|
Классы проверок данных |
|
|
|
|
Класс проверок |
Тег |
Функции |
DoubleRangeValidator |
validateDoubleRange |
Проверяет локальные данные от компонента |
|
|
на нахождение в определённом диапазоне. |
|
|
Значение должно быть с плавающей точкой |
LengthValidator |
validateLength |
Проверяет длину данных на нахождение |
|
|
в определённом диапазоне. |
|
|
Значение должно быть типа java.lang.String |
LongRangeValidator |
validateLongRange |
Проверяет локальные данные от компонента |
|
|
на нахождение в определённом диапазоне. |
|
|
Значение должно быть длинным числом |
RegexValidator |
validateRegEx |
Проверяет локальные данные от компонента |
|
|
регулярным выражением пакета java.util.regex |
BeanValidator |
validateBean |
Регистрирует внешний бин для компонента |
RequiredValidator |
validateRequired |
Проверяет наличие локальных данных |
|
|
от компонента EditableValueHolder |
69
Подобно стандартным преобразователям, каждая из этих проверок имеет одно
или более связанных с ней стандартных сообщений об ошибке. Например, сообщение
об ошибке, которое отображается, когда значение превышает максимум, допустимый в LongRangeValidator, выглядит следующим образом:
{1}: Validation Error: Value is greater than allowable maximum of "{0}"
В этом случае параметр подстановки {1} заменяется тегом компонента или id, а
параметр подстановки {0} заменяется максимально допустимой величиной.
7.2.3.1. Проверка вводимых значений компонента
Чтобы обеспечить автоматическую проверку поступающих от компонент дан-
ных с использованием конкретной проверки, ее нужно зарегистрировать в компоненте
одним из следующих способов:
•поместить соответствующий тег проверки (показанный в табл. 7.3) в тег ком-
понента;
•сослаться на метод, который выполняет проверку, из атрибута validator тега компонента;
•поместить тег validator внутрь тега компонента и использовать или его атрибут validatorId, или атрибут binding, чтобы ссылаться на проверку. Атрибут validatorId работает аналогично атрибуту converterId тега преобразователя.
Имейте в виду, что проверка может выполняться только для компонент, которые
реализуют интерфейс EditableValueHolder, поскольку только эти компоненты принимают от клиента данные, которые могут быть проверены.
7.2.3.2. Использование LongRangeValidator
Следующий пример показывает, как использовать проверку validateLongRange для компонента ввода числовых данных:
<h:inputText id="quantity" size="4" value= "#{item.quantity} " >
<f:validateLongRange minimum="1"/> </h:inputText>
<h:message for="quantity"/>
Тег inputText требует, чтобы пользователь вводил число, которое не меньше
единицы. Атрибут size определяет, что число может состоять не более чем из четырех
цифр. Тег validateLongRange также может иметь атрибут максимума, который вы можете установить для вводимого числа.
Атрибуты всех стандартных тегов проверок требуют EL-выражения. Это озна-
чает, что атрибуты могут ссылаться на свойства внешних бинов, а не определять кон-
станты. Например, тег validateLongRange в предыдущем примере может ссылаться на
свойство внешнего бина, задающее минимум, чтобы получать минимальное допусти-
мое значение в проверке:
<f:validateLongRange minimum="#{ShowCartBean.minimum}" />
Ссылки на метод внешнего бина
Тег компонента имеет набор атрибутов для ссылок на методы бинов, выпол-
няющих определённые функции для компонента, связанного с тегом. Эти атрибуты перечислены в табл. 7.4.
70

Таблица 7.4
|
Атрибуты связывания тега с методами бинов |
|
|
Атрибут |
Функция |
action |
Ссылка компонента на бин для навигации |
|
и возврата строки с логическим переходом |
actionListener |
Ссылка на бин для обработки события |
validator |
Ссылка на метод бина для проверки данных компонента |
valueChangeListener Ссылка на метод бина для обработки события изменения значения
Только компоненты, реализующие ActionSource, могут использовать атрибуты action и actionListener. Только компоненты, реализующие EditableValueHolder, могут
использовать атрибуты validator или valueChangeListener.
Тегкомпонентассылаетсяна методвнешнегобина,используявыражение-метод как значение одного из атрибутов. Метод, на который ссылается атрибут, должен удо-
влетворять конкретным требованиям сигнатуры (структуры параметров и тела), кото-
рая определена тегом в TLD. Например, определение атрибута validator тега inputText
в описании библиотеки в файле html_basic.tld следующее:
void validate(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
7.2.4. Ссылки на методы навигации
Если ваша страница включает компоненты (как например, кнопки или гиперс-
сылки) для перехода приложения на другую страницу, когда компонент активирован,
тег соответствующего компонента должен включать атрибут действия action. Этот атрибут:
•определяет логическую строку-результат, которая сообщает навигатору при-
ложения страницу для последующего перехода;
•указывает метод внешнего бина, который выполняет некоторую обработку и возвращает логическую строку-результат навигатору.
Следующий пример показывает, как ссылаться на метод навигации:
<h:commandButton
value="#{bundle.Submit}" action="#{cashier.submit}" />
7.2.5. Ссылки на обработчик события
Если компонент на вашей странице генерирует событие action и если это событие обрабатывается внешним методом, то надо сослаться на метод, используя атри-
бут actionListener. Например:
<h:commandLink id="NAmerica" action="bookstore" actionListener="#{localeBean.chooseLocaleFromLink}">
Атрибут actionListener этого тега компонента ссылается на метод chooseLocaleFromLink с использованием выражения для метода. Метод chooseLocaleFromLink обрабатывает событие, когда пользователь щёлкает по гиперс-
сылке, предоставленной этим компонентом.
71
7.2.6. Обращение к методу проверки данных
Для проверки ввода компонентов на странице внешним методом нужна ссылка
на метод в теге, используя атрибут validator, например:
<h:inputText id="email" value="#{checkoutFormBean.email}" size="25" maxlength="125" validator="#{checkoutFormBean.validateEmail}"/>
7.2.7. Обращение к методу обработки события
Для обработки сообщения об изменении значения для компонента на вашей
странице внешним методом нужно сослаться на метод с использованием тега или
атрибута valueChangeListener, например:
<h:inputText
id="name"
size="50"
value="#{cashier.name}"
required="true">
<f:valueChangeListener type="listeners.NameChanged" /> </h:inputText>
<h:inputText
id="name"
size="50"
value="#{cashier.name}"
required="true" valueChangeListener="#{cashier.processValueChange}" />
</h:inputText>
72