Компоненты JavaBeans в JSP-страницах
Компоненты JavaBeans представляют собой классы Java, которые могут быть легко использованы повторно и объединены в приложение. Любой класс Java, который соответствует определенным требованиям проектирования, может быть компонентом JavaBeans.
Технология JavaServer Pages непосредственно поддерживает использование компонентов JavaBeans при помощи элементов языков JSP. Вы можете легко создавать и инициализировать компоненты, получать и устанавливать их свойства. Эта глава предоставляет основную информацию о компонентах JavaBeans и элементах языка JSP для доступа к компонентам в JSP-страницах. Дополнительная информация о модели компонентов JavaBeans находится на http://java.sun.com/products/javabeans.
Содержание
1 Требования к проектированию компонентов JavaBeans
2 Почему применяются компоненты JavaBeans?
3 Создание и использование компонента JavaBeans
4 Установка свойств компонента JavaBeans
5 Извлечение свойств компонена JavaBeans
1 Требования к проектированию компонентов JavaBeans
Требования к проектированию компонентов JavaBeans определяют свойства класса и методы public, дающие доступ к свойствам.
Свойство компонента JavaBeans может быть:
для чтения/записи, только для чтения, только для записи
простым (содержащим одно значение) или индексным (представляющим массив значений)
Не существует требования, чтобы свойство реализовывалось переменной экземпляра. Свойство просто должно быть доступно через методы public, следующие определенным правилам:
Для каждого читаемого свойства компонент должен иметь метод в виде PropertyClass getProperty() {...}
Для каждого записываемого свойства компонент должен иметь метод в виде setProperty(PropertyClass pc){...}
Кроме методов свойств компонент JavaBeans должен определить конструктор без параметров.
JSP-страницы приложения Duke's Bookstore enter.jsp, bookdetails.jsp, catalog.jsp и showcart.jsp используют компоненты JavaBeans database.BookDB и database.BookDetails. BookDB обеспечивает компоненту JavaBeans внешний интерфейс к корпоративному компоненту BookDBEJB. Оба компонента широко используются ориентированными на компоненты пользовательскими тегами (см. раздел Теги, определяющие переменные сценариев). JSP-страницы showcart.jsp и cashier.jsp используют cart.ShoppingCart для представления корзины покупок клиента.
JSP-страницы catalog.jsp, showcart.jsp и cashier.jsp используют компонент JavaBeans util.Currency для форматирования валюты в зависящем от региона формате. Компонент имеет два записываемых свойства, locale и amount, и одно читаемое свойство, format. Свойство format не соответствует ни одной переменной экземпляра, а возвращает функцию свойств locale и amount.
public class Currency {
private Locale locale;
private double amount;
public Currency() {
locale = null;
amount = 0.0;
}
public void setLocale(Locale l) {
locale = l;
}
public void setAmount(double a) {
amount = a;
}
public String getFormat() {
NumberFormat nf = NumberFormat.getCurrencyInstance(locale);
return nf.format(amount);
}
}
2 Почему применяются компоненты JavaBeans?
В объявлении или скриптлете JSP-страница может использовать любой тип объекта языка программирования Java. Следующий скриптлет создает корзину покупок книжного магазина и сохраняет его как атрибут сессии:
<% ShoppingCart cart = (ShoppingCart)session. getAttribute("cart"); // Если пользователь не имеет корзины, создать новую if (cart == null) { cart = new ShoppingCart(); session.setAttribute("cart", cart); } %>
Если объект корзины покупок соответствует требованиям JavaBeans, JSP-страницы могут использовать JSP-элементы для создания объектов и обращения к ним. Например, страницы приложения Duke's Bookstore bookdetails.jsp, catalog.jsp, и showcart.jsp замещают скриптлет гораздо более лаконичным JSP-элементом useBean:
<jsp:useBean id="cart" class="cart.ShoppingCart" scope="session"/>
3 Создание и использование компонента JavaBeans
Вы объявляете, что JSP-страница будет использовать компонент JavaBeans, применяя один из двух форматов:
<jsp:useBean id="beanName" class="fully_qualified_classname" scope="scope"/>
или
<jsp:useBean id="beanName" class="fully_qualified_classname" scope="scope"> <jsp:setProperty .../> </jsp:useBean>
Второй формат используется в том случае, если вы хотите включить оператор jsp:setProperty, описанный в следующем разделе, для инициализации свойств компонента.
Элемент jsp:useBean объявляет, что страница будет использовать компонент, хранящийся и доступный из указанной области видимости, которая может быть application, session, request, или page. Если такого объекта не существует, оператор создает компонент и сохраняет его как атрибут объекта области видимости (см. раздел Использование объектов области видимости). Значение атрибута id определяет имя (name) компонента в области видимости и идентификатор (identifier), используемый для ссылки на компонент в других JSP-элементах и скриптлетах.
Примечание: В разделе Элементы сценариев JSP упоминалось, что вы должны импортировать все классы и пакеты, используемые JSP-страницей. Это правило немного меняется, если к классу обращаются только через элемент useBean. В этих случаях вы должны импортировать класс только тогда, когда он находится в непоименованном пакете. Например, в разделе Что такое JSP-страница? страница index.jsp импортирует класс MyLocales. Однако, в примере Duke's Bookstore все классы содержатся в пакетах и, таким образом, не импортируются явно.
Следующий элемент создает экземпляр Currency, если он не существует, сохраняет его как атрибут объекта session и делает компонент доступным в течение сессии через идентификатор currency:
<jsp:useBean id="currency" class="util.Currency" scope="session"/>
4 Установка свойств компонента JavaBeans
В JSP-странице существует два способа установить свойства компонента JavaBeans: при помощи элемента jsp:setProperty или при помощи скриптлета
<% beanName.setPropName(value); %>
Синтаксис элемента jsp:setProperty зависит от источника значения свойства. В таблицу 12-1 сведены различные способы установки свойства компонента JavaBeans с использованием элемента jsp:setProperty.
Таблица 12-1. Установка свойств компонента JavaBeans
Источник значения | Синтаксис элемента |
---|---|
Строковая константа | <jsp:setProperty name="beanName" property="propName" value="string constant"/> |
Параметр запроса | <jsp:setProperty name="beanName" property="propName" param="paramName"/> |
Имя параметра запроса соответствует свойству компонента | <jsp:setProperty name="beanName" property="propName"/> <jsp:setProperty name="beanName" property="*"/> |
Выражение | <jsp:setProperty name="beanName" property="propName" value="<%= expression %>"/> |
beanName должно быть таким же, как и указанное для атрибута id в элементе useBean.
В компоненте JavaBeans должен существовать метод setPropName.
paramName должен быть именем параметра запроса.
Свойство, устанавливаемое из константы-строки или параметра запроса, должно иметь тип, перечисленный в таблице 12-2. Поскольку и константа, и параметр запроса являются строками, Web-контейнер автоматически преобразовывает значение в тип свойства; применяемое преобразование приводится в таблице. Значения String могут использоваться для присваивания значений свойству, имеющему класс PropertyEditor. В этом случае используется метод setAsText(String). Ошибка преобразования возникает, если метод генерирует исключительную ситуацию IllegalArgumentException. Значение, присваиваемое индексному свойству, должно быть массивом, а описанные правила применяются для элементов.
Таблица 12-2 Корректные присваивания значений
Тип свойства | Преобразование строкового значения |
---|---|
Свойство компонента | Использует setAsText(string-literal) |
boolean или Boolean | Как указано в java.lang.Boolean.valueOf(String) |
byte или Byte | Как указано в java.lang.Byte.valueOf(String) |
char или Character | Как указано в java.lang.String.charAt(0) |
double или Double | Как указано в java.lang.Double.valueOf(String) |
int или Integer | Как указано в java.lang.Integer.valueOf(String) |
float или Float | Как указано в java.lang.Float.valueOf(String) |
long или Long | Как указано в java.lang.Long.valueOf(String) |
short или Short | Как указано в java.lang.Short.valueOf(String) |
Object | new String(string-literal) |
Вы должны использовать выражение времени исполнения для установки значения свойства, тип которого является составным типом языка программирования Java. Вспомните из раздела Выражения, что JSP-выражения используются для вставки значения выражения языка сценариев, преобразованного в String, в поток, возвращаемый клиенту. При использовании в элементе setProperty выражение просто возвращает свое значение; не выполняется никакого автоматического преобразования. Следовательно, тип, возвращенный из выражения, должен соответствовать или быть преобразуемым в тип свойства.
Приложение Duke's Bookstore демонстрирует, как использовать элемент setProperty и скриптлет для установки текущей книги для вспомогательного компонента базы данных. Например, bookstore3/bookdetails.jsp использует форму
<jsp:setProperty name="bookDB" property="bookId"/>
в то время как bookstore2/bookdetails.jsp использует форму
<% bookDB.setBookId(bookId); %>
Следующие фрагменты из страницы bookstore3/showcart.jsp демонстрируют, как проинициализировать компонент валюты, используя объект Locale и количество, определенное вычислением выражений времени запроса. Поскольку первая инициализация вложена в элемент useBean, она выполняется только при создании компонента.
<jsp:useBean id="currency" class="util.Currency" scope="session"> <jsp:setProperty name="currency" property="locale" value="<%= request.getLocale() %>"/> </jsp:useBean>
<jsp:setProperty name="currency" property="amount" value="<%=cart.getTotal()%>"/>
5 Извлечение свойств компонена JavaBeans
Существует несколько способов извлечь свойства компонента JavaBeans. Два метода (элемент и выражение jsp:getProperty) преобразовывают значение свойства в String и вставляют значения в текущий скрытый объект out:
- <jsp:getProperty name="beanName" property="propName"/>
- <%= beanName.getPropName() %>
Для обоих методов beanName должен быть таким же, как указанный для атрибута id в элементе useBean, а в компоненте JavaBeans должен быть определен метод getPropName.
Если нужно извлечь значение свойства без преобразования и вставить его в объект out, вы должны использовать скриптлет:
<% Object o = beanName.getPropName(); %>
Обратите внимание на различия между выражением и скриптлетом: в выражении, в отличие от скриптлета, после открывающего % записан знак равенства (=) и оно не заканчивается точкой с запятой.
В приложении Duke's Bookstore показывается, как используются обе формы для извлечения форматированного значения валюты из компонента currency и вставки его в страницу. Например, bookstore3/showcart.jsp использует форму
<jsp:getProperty name="currency" property="format"/>
а bookstore2/showcart.jsp использует форму
<%= currency.getFormat() %>
В странице приложения Duke's Bookstore bookstore2/showcart.jsp для извлечения количества книг из компонента корзины покупок и открытия условной вставки текста в выходной поток используется следующий скриптлет:
<% // Распечатать количество предметов в корзине покупок int num = cart.getNumberOfItems(); if (num > 0) { %>
Хотя скриптлеты очень полезны при динамической обработке, использование пользовательских тегов (см. главу 13) для доступа к свойствам объекта и выполнения передачи управления считается лучшим подходом. Например, в bookstore3/showcart.jsp скриптлет замещается следующими пользовательскими тегами:
<bean:define id="num" name="cart" property="numberOfItems" /> <logic:greaterThan name="num" value="0" >
На рисунке 12-1 подведен итог и показано, где хранятся различные типы объектов и как к этим объектам можно получить доступ из JSP-страницы. Объекты, созданные в теге jsp:useBean, хранятся как атрибуты объектов области видимости и доступны через теги jsp:[get|set]Property, скриптлеты и выражения. Объекты, созданные в объявлениях и скриптлетах, хранятся как переменные класса сервлета JSP-страницы и доступны в скриптлетах и выражениях.
Рисунок 12-1. Получение доступа к объектам из JSP-страницы