- •Обозначения и сокращения
- •введение
- •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. Внешние объекты (JavaBeans)
Типичное приложение JSF содержит один или более внешних объектов, ко-
торые управляют объектами, связываются с компонентами UI, использованными на конкретной странице. Внешние бины являются компонентами JavaBeans, которые вы
должны сконфигурировать. Есть особенности, определяемые ролью JavaBeans в ор-
ганизации и функционировании компонент JSF. Ниже приводятся основные сведения
о создании, конфигурации и использовании внешних бинов в приложении.
8.1. Создание класса внешних объектов
Внешние бины являются экземплярами классов с конструктором без параме-
тров, набором методов get/set для доступа к свойствам, используемым компонентами,
и методов, которые выполняют бизнес-логику для компонента.
Каждое свойство бина может быть связано:со значением атрибута компонента,
с экземпляром компонента,экземпляром конвертера,экземпляром слушателя,экземпляром для проверки значений.
Наиболее общие функции, которые выполняют методы внешних бинов, включают следующее:
подтверждение правильности данных от компонентов;обработка событий, созданных компонентом;
обработка данных для определения следующей страницы, на которую при-
ложение должно перейти (навигация).
Как у всех компонент JavaBeans, свойства состоят из полей приватных данных и набора методов set/get доступа к ним, как показано кодом из примера GuessNumber:
private Integer userNumber = null; // место хранения значения свойства
...
public void setUserNumber(Integer user_number) { |
// метод set |
userNumber = user_number; |
|
} |
|
public Integer getUserNumber() { |
// метод get |
return userNumber; |
|
} |
|
public String getResponse() { |
// прочие методы |
... |
|
} |
|
Поскольку все внешние бины следуют соглашениям JavaBeans, вы можете использовать объекты, ранее написанные для JSP-технологии.
Когда свойство бина связано со значением атрибута компонента, оно может
быть любым базовым примитивом, числовым типом или любым объектным типом
73
языка Java, для которого приложение имеет доступ к подходящему преобразова-
телю. Например, свойство может быть типа Date, если приложение имеет доступ к преобразователю типа Date в String и обратно. Необходимость использования пре-
образователей продиктована тем, что клиенту и от клиента данные посылаются как
строки — следствие использования протокола http для их передачи.
Когда свойство бина связано с экземпляром компонента, тип должен быть та-
ким же, как и тип компонента. Например, если свойство связано с SelectBoolean, то оно должно принимать и возвращать объект класса SelectBoolean.
Аналогично, если свойство связано с преобразователем, проверкой или экзем-
пляром слушателя, оно должно быть класса, подходящего для преобразователя, про-
верки значений или слушателя.
Использование унифицированного языка выражений EL для ссылок на внешние объекты
Для связывания значений компонентов и свойств внешних объектов или для ссылок на методы внешних объектов из тегов компонент авторы страниц используют
унифицированный язык выражения (EL). Он имеет следующие черты:отложенная оценка выражений;
способность использовать выражения-значения как для чтения, так и для записи данных;
использование выражений для подключения необходимых методов.
Отложенная оценка выражений необходима, поскольку жизненный цикл
JavaServer Faces разделен на отдельные фазы: обработка событий у компонент, преобразование данных и подтверждение правильности, передача данных во внешние бины. Сервер должен быть способен задержать оценку выражений, пока не наступила соответствующая фаза жизненного цикла. Следовательно, атрибут тега всегда исполь-
зует синтаксис задержанных вычислений, который задан разделителями «#{ . . . }».
Для того чтобы хранить данные во внешних объектах, почти все атрибуты тегов JSF используют выражения value, которые допускают как получение, так и запись данных во внешних объектах. Наконец, некоторые атрибуты компонентных тегов принимают имена методов, обрабатывающих компонентные события, контролирующих
или преобразовывающих компонентные данные.
Для иллюстрации тега, использующего унифицированный EL, будем полагать, что тег userNo приложения guessNumber ссылается на свой метод validate вместо использования LongRangeValidator, выполняющего стандартную проверку ввода поль-
зователя:
<h:inputText id="userNo" value="#{userNumberBean.userNumber}" validator="#{userNumberBean.validate}" />
Этот тег связывает компонент ввода userNo со свойством userNumber внешне-
го объекта userNumberBean, возвращающим данные с использованием выражения value. Оноиспользуетвыражение,чтобыссылатьсянаметодuserNumberBean.validate,
который выполняет контроль полученного значения. Локальное значение — любое данное, которое пользователь вводит в поле, соответствующее тегу. Этот метод про-
верки вызывается тогда, когда выражение оценивается в фазе контроля в жизненном
цикле запроса, поступившего от клиента.
74
Почти все атрибуты тегов допускают выражения. В дополнение к свойствам
объектов, значения выражения могут также ссылаться на списки, карты, массивы, встроенные объекты и пачки ресурсов.
Другое использование выражений связывает экземпляр компонента со свой-
ством внешнего объекта. Этот механизм позволяет в период исполнения приложения
программно изменять атрибуты тегов. Автор страницы делает это с помощью связы-
вающего атрибута binding со свойством, содержащим описание компонента:
<inputText binding="#{userNumberBean.userNoComponent}" />
Дополнительно к использованию выражений со стандартными компонентными
тегами, вы можете также конфигурировать ваши собственные свойства компонен-
тов, чтобы вычислять выражения, создавая для них экземпляры ValueExpression или
MethodExpression.
8.2. Описание свойств бинов
Как сказано выше, свойство внешнего бина может быть связанным с одним из
следующих пунктов:
значение данных компонента,
экземпляр компонента,
реализация преобразователя,
реализация слушателя,
реализация проверки (validator).
Эти свойства следуют соглашениям о компонентах JavaBeans (бины).
Тег компонента связывает его со свойством внешнего бина, используя атрибут value, или связывает экземпляр компонента со свойством внешнего бина, используя
атрибут binding. Аналогично преобразователь, слушатель и проверка для тега используют атрибуты binding, чтобы связывать их реализации со свойством внешнего бина.
Связываемые свойства и данные компонента должны иметь одинаковый тип. Например, если компонент имеет тип SelectBoolean, то и внешнее свойство должно возвращать данное типа SelectBoolean.
Описание связи свойства с атрибутами данных компонента
В табл. 8.1 содержатся компоненты и типы их данных.
|
Таблица 8.1 |
|
|
Компоненты и типы их значений |
|
|
|
|
Компонент |
Тип данных |
|
Input, Output, SelectItem, |
Любой основной примитив и числовые и другие типы языка |
|
SelectOne |
программирования Java, для которых доступна подходящая |
|
|
реализация конвертера |
|
Data |
Массив бинов, список бинов, одиночный бин, java.sql.ResultSet, |
|
|
javax.servlet.jsp.jstl.sql.Result, javax.sql.RowSet |
|
SelectBoolean |
boolean или Boolean |
|
SelectItems |
java.lang.String, Collection,Array, Map |
|
SelectMany |
Массив или список элементов любого стандартного типа |
|
75
Свойства компонент Input и Output
В следующем примере тег h:inputText связывает значение компонента со свойством name внешнего бина с именем cashier в классе CashierBean:
<h:inputText id="name" size="50» value="#{cashier.name}" </h:inputText>
Следующий фрагмент кода CashierBean показывает тип свойства, связанного
с предыдущим компонентным тегом. Обратите внимание на правила написания имен методов и свойств: свойство и внутренняя переменная — name, методы — setName
и getName:
private String name = null;
public void setName(String name) { // Запись свойства this.name = name;
}
public String getName() { |
// Чтение свойства |
return this.name; |
|
} |
|
Чтобы преобразовывать значение компонентов Input или Output, вы можете использовать преобразователь или создать связь свойства бина с компонентом сопоставимого типа. Ниже приведен пример из описания DateTimeConverter, который отображает дату заказа книги:
<h:outputText value="#{cashier.shipDate}"> <f:convertDateTime dateStyle="full" />
</h:outputText>
Свойство,представленноеэтимтегом,должнобытьтипаjava.util.Date.Фрагмент описания класса CashierBean показывает объявление свойства shipDate, которое связано со значением тега в предыдущем примере:
private Date shipDate; public Date getShipDate() {
return this.shipDate;
}
public void setShipDate(Date shipDate) { this.shipDate = shipDate;
}
Свойства типа Data
Компоненты данных из таблиц БД должны иметь один из типов, указанных в табл. 8.1. Пример начальной части тега dataTable:
<h:dataTable id="items"
...
value="#{cart.items}" var="item" >
Значение выражения атрибута value указывает на свойство items бина с именем cart. Бин cart поддерживает отображение набора бинов класса ShoppingCartItem
в хранилище данных, например, средствами Persistence.
76
Метод getItems бина cart возвращает список экземпляров ShoppingCartItem, которые хранились в базе данных, когда клиент добавлял книги в корзину. Пример по-
казан в следующем коде:
public synchronized List getItems() { |
// Создание копии |
List results = new ArrayList(); |
|
results.addAll(this.items.values()); |
// Заполнение копии |
return results; |
// Копия как результат |
} |
|
Все компоненты, содержащиеся в компоненте Data, связаны со свойствами бина cart, который помещен в компонент Data. Например, тег h:outputText показывает
название книги в таблице:
<h:commandLink action="#{showcart.details}"> <h:outputText value="#{item.item.title}"/>
</h:commandLink>
Свойства SelectBoolean
Свойства бина, которые содержат данные SelectBoolean, должны быть типа boolean или Boolean. Пример тега selectBooleanCheckbox связывает компонент и
свойство логического типа:
<h:selectBooleanCheckbox title="#{bundle.receiveEmails}" value="#{custFormBean.receiveEmails}" >
</h:selectBooleanCheckbox>
<h:outputText value="#{bundle.receiveEmails}">
Пример свойства бина, которое может быть связано с тегом этого компонента:
protected boolean receiveEmails = false;
...
public void setReceiveEmails(boolean receiveEmails) { this.receiveEmails = receiveEmails;
}
public boolean getReceiveEmails() { return this.receiveEmails;
}
Свойство SelectMany
Поскольку компонент SelectMany позволяет пользователю выбирать один или
более пунктов из списка, этот компонент должен отображаться в свойство бина типа
List или array. Это свойство представляет набор выбранных в настоящее время пунктов из списка доступных. Пример тега SelectingMultiple:
<h:selectManyCheckbox
id="newsletters"
layout="pageDirection"
value="#{cashier.newsletters}">
<f:selectItems value="#{cashier.newsletters}"/> </h:selectManyCheckbox>
77
Пример свойства бина, которое отображается в значение тега selectManyCheckbox из предыдущего примера:
protected String newsletters[] = new String[0];
public void setNewsletters(String newsletters[]) { this.newsletters = newsletters;
}
public String[] getNewsletters() { return this.newsletters;
}
Компоненты SelectItem и SelectItems используются, чтобы задавать пункты в
компоненте SelectMany.
Свойства SelectOne
Свойства SelectOne принимают те же типы, как свойства Input и Output, посколь-
ку компонент SelectOne представляет единственный выбранный пункт из множества
пунктов. Этот пункт может быть любым простым типом или любым данным, для кото-
рого вы можете применить преобразователь.
Пример тега selectOneMenu:
<h:selectOneMenu id=”shippingOption” required=”true”
value=”#{cashier.shippingOption}”> // Куда принять результат <f:selectItem
itemValue=”2” // Вариант результата itemLabel=”#{bundle.QuickShip}”/> // Его представление
<f:selectItem
itemValue=”5”
itemLabel=”#{bundle.NormalShip}”/>
<f:selectItem
itemValue=”7”
itemLabel=”#{bundle.SaverShip}”/>
</h:selectOneMenu>
Пример соответствующего тегу свойства бина shippingOption:
private String shippingOption = "2"; // По умолчанию public void setShippingOption(String shippingOption) {
this.shippingOption = shippingOption;
}
public String getShippingOption() { return this.shippingOption;
}
Заметьте, что свойство shippingOption представляет выбранный к настоящему времени пункт из списка в компоненте SelectOne.
Компоненты SelectItem и SelectItems используются, чтобы задавать пункты в
компоненте SelectOne.
78
Свойство SelectItem
Компонент SelectItem представляет одно значение в наборе значений в ком-
поненте SelectMany или SelectOne. Компонент SelectItem может быть связанным со свойством внешнего бина типа SelectItem. Компонент SelectItem сформирован из объ-
екта, представляющего значение, и двух строк, представляющих этикетку и описание
объекта SelectItem.
Примера тега selectOneMenu содержит теги selectItem, которые устанавливают
строки списка пунктов на странице. Пример свойства бина, которое может установить значения для этого списка в бине:
SelectItem itemOne = null; SelectItem getItemOne(){ return itemOne;
}
void setItemOne(SelectItem item) { itemOne = item;
}
Свойство SelectItems
Компоненты SelectItems — потомки компонентов SelectMany и SelectOne.
Каждый компонент SelectItems состоит из множества экземпляров SelectItem или кол-
лекции объектов, как например, массив, список или даже таблица БД.
Свойства для SelectItems с объектами SelectItem
Вы можете заполнить SelectItems объектами SelectItem во внешнем бине:
1.Во внешнем бине создайте список, который связан с компонентом
SelectItem.
2.Определите множество объектов SelectItem, установите их значения и
заполните список объектами SelectItem.
Пример фрагмента кода внешнего бина, который показывает, как создать свой-
ство SelectItems:
import javax.faces.component.SelectItem;
...
protected ArrayList options = null;
protected SelectItem newsletter0 = // Новый элемент выбора new SelectItem("200", "Duke’s Quarterly", "");
... // Другие элементы выбора
//в конструкторе заполнить список элементов options.add(newsletter0); options.add(newsletter1); options.add(newsletter2);
...
//Свойство для первого элемента списка public SelectItem getNewsletter0(){
return newsletter0;
}
void setNewsletter0(SelectItem firstNL) { newsletter0 = firstNL;
79
}
...
// Другие свойства SelectItem public Collection[] getOptions(){
return options;
}
public void setOptions(Collection[] options){ this.options = new ArrayList(options);
}
Сначала код инициализирует опции как список. Каждое свойство newsletter задаётся некоторым значением и добавляется в список. Наконец, код включает обяза-
тельные методы доступа setOptions и getOptions для свойства options.
Запись свойств, связанных с компонентами
Связанные с экземплярами компонентов свойства возвращают и принимают
сами экземпляры компонент, а не данные от компонент. Следующие компоненты задаются свойством внешнего бина:
<h:selectBooleanCheckbox
id="fanClub"
rendered="false" binding=”#{cashier.specialOffer}"
/>
<h:outputLabel for="fanClub" rendered="false" binding="#{cashier.specialOfferText}" > <h:outputText id="fanClubLabel"
value="#{bundle.DukeFanClub}"
/>
</h:outputLabel>
Тег selectBooleanCheckbox отображается на странице переключателем и свя-
зывает компонент fanClub типа SelectBoolean со свойством specialOffer объекта
CashierBean. Тег outputLabel связывает компонент fanClubLabel (который отображает этикетку переключателя) со свойством specialOfferText бина класса CashierBean. Если пользователь заказывает покупку стоимостью более чем $100 и щёлкает кнопку Submit, то метод submit бина CashierBean устанавливает оба свойства rendered компонент в true, вызывая отображение текущего состояния переключателя и этикетки при
повторном отображении страницы. Это позволяет динамически изменять внешний вид элемента на странице, управляя им из бина. Эта техника полезна при разработке
интерфейсов, настраиваемых на окружение пользователем.
Поскольку компоненты, соответствующие тегам примера, связаны со свойствами внешнего бина, эти свойства должны соответствовать типам компонент. Это озна-
чает, что свойство specialOfferText должно быть типа Output, а свойство specialOffer
должно быть типа SelectBoolean:
Output specialOfferText = ...;
public Output getSpecialOfferText() { // Дай компонент
80
return this.specialOfferText;
}
public void setSpecialOfferText(UIOutput specialOfferText) { this.specialOfferText = specialOfferText;
}
SelectBoolean specialOffer = ...;
public SelectBoolean getSpecialOffer() { // Дай компонент return this.specialOffer;
}
public void setSpecialOffer(UISelectBoolean specialOffer) { this.specialOffer = specialOffer;
}
Описание свойств связи с конвертерами, слушателями и проверками
Все стандартные преобразователи, слушатели и проверки включают поддержку
атрибута связи со свойствами внешних бинов. Работа с ними аналогична приведённо-
му ниже примеру.
Следующий пример показывает стандартный тег convertDateTime, использующийвыражение,чтобысвязатьэкземплярDateTimeConverter сосвойствомconvertDate
бина LoginBean:
<h:inputText value="#{LoginBean.birthDate}"> <f:convertDateTime binding="#{LoginBean.convertDate}" />
</h:inputText>
Следовательно, свойство convertDate должно принимать и возвращать объект класса DateTimeConverter, как показано здесь:
private DateTimeConverter convertDate;
public DateTimeConverter getConvertDate() {
...
return convertDate;
}
public void setConvertDate(DateTimeConverter convertDate) { convertDate.setPattern(“EEEEEEEE, MMM dd, yyyy”); this.convertDate = convertDate;
}
Поскольку преобразователь связан со свойством внешнего бина, свойство мо-
жет модифицировать атрибуты преобразователя или добавлять новое функциональное назначение. В предыдущем примере свойство устанавливает шаблон даты, который использует преобразователь, чтобы выполнять грамматический разбор данных клиента в объекте Date.
81