Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:JAVA. Серверные приложения
.pdf
Часть 2 Java Server Page 131
public int doEndTag() {
return EVAL_PAGE;}
Как видно, класс не использует интерфейс Tag, а порожден от Tag-
Suuport класса. Во второй и пятой строках определены уже известные
методы doStartTag() и doEndTag(), первый из которых выводит замечательную строку приветствия на английском языке. Если происходит какая-либо неприятность, то генерируется исключительная ситуация.
16.2. Body-tag
Другой тип тегов (body-tag) может содержать любые элементы
•
между определением начала и конца тега, такие, как другие поль-
зовательские теги, стандартные теги или JSP-скриплеты и конечно
же HTML-элементы.
<mylib:tagA attr1="aaa" attr2="bbb" >
<H2> body of tagA</H2> You have seen this text
<mylib:counter /> times!
<mylib:repeater repeat=4> Hello World! </mylib:repeater> </mylib:tagA>
Класс, реализующий интерфейс javax.servlet.jsp.tagext.BodyTag,
имеет дополнительные методы обработки текста, находящегося между
открывающими и закрывающими элементами тега. Как и атрибуты
обычного тега, этим атрибутам может присваиваться некое значение,
результатом присвоения и будет являться значение атрибута <teglib:myteg date="<%= _date()%>">
Основные шаги по созданию тега с телом:
1. t.doStartTag();
2. out = pageContext.pushBody();
3. t.setBodyContent(out);
4. t.doBodyInit();
5. t.doAfterBody();
6. t.doEndTag().
О методе doStartTag() уже упоминалось выше, единственное отличие
îò предшественника — â возвращаемом значении, равное
EVAL_BODY_INCLUDE, указывающие на существование тела у тега.
Если же тело у тега отсутствует, то данный метод возвращает значение
SKIP_BODY. Во второй строке формируется объект, содержащий
встроенные данные. Для считывания значений из тела тега используются стандартные методы getString() и getReader(), метод writeOut (out)
предназначен для записи в тело. Третья строка указывает на проведение операции записи в тело тега. Четвертая строка используется для
инициализации тела тега. В теле тега содержатся операторы (данные),
обрабатываемые данным тегом. И пятая строка определяет метод, в теле которого определяются действия, выполняемые после того, как тело
тега будет обработано. Если тело тега будет использовать в дальнейшем
метод doStartTag(), возвращая значение EVAL_BODY_TAG, в противном случае метод doStartTag() возвращает значение SKIP_BODY, гово-

132 Часть 2 Java Server Page
рящий о том, что после выполнения кода, содержащегося в теле тега, к
этому коду больше не обращаться.
import java.sql;
•
import javax.servlet .jsp.tagext;
•
public class QueryTag extends BodyTagSupport {
•
public int doAfterBody() throws JspTagException {
•
BodyContent bc = getBodyContent();
•
String query = bc.getString();
•
bc.clearBody();
•
try {
•
Statement stmt = connection.createStatement();
•
result = stmt.executeQuery(query);
•
} catch (SQLException e) {
•
throw new JspTagException("QueryTag: " +e.getMessage());}
•
return SKIP_BODY;}
•
Операторы импорта, указанные в первых строках, необходимы для
создания тега JSP, работающего с базой данных (первый оператор import). В третьей строке создается класс тега, расширенный от класса
BodyTegSupport. При помощи данного класса создаются теги, содержащие тело. В четвертой строке переопределяется метод doAfterBody().
В данном методе создаются перемен
ные, необходимые для работы с телом тега. Строки девятая и деся-
тая — обычные объекты, часто используемые при организации работы
с базами данных. Именно из тела тега будет браться необходимая информация для подключения к базе данных, а также SQL-запрос, который будет выполнен, — шестая строка.
В обоих тегах предусмотрена возможность использования перемен-
ных, которые после можно будет использовать в JSP-странице:
<teglib:myteg id="tagA" attr="name" >
<teglib:myteg2 attr="id">
Если атрибут имеет значение id, то для инициализации этого атри-
бута нет необходимости использовать методы setXXX()/getXXX(). Для
правильной работы тега значения присваиваемые атрибутам, должны
пройти проверку на соответствие типов данных.
16.3. Библиотека пользовательских тегов
Для обработки пользовательских тегов JSP-engine обращается к спе-
циальной структуре, содержащей описание созданных тегов. Все пользовательские теги описываются в библиотеке тегов (Tag Library), представляющие текстовый файл с расширением .tld., имеющего XMLструктуру. В библиотеке описан синтаксис каждого тега и классы, содержащие описанные теги.
Обязательный заголовок XML

Часть 2 Java Server Page 133
<?xml version="1.0" encoding="ISO-8859-1" ?>
•
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP
•
Tag Library 1.1//EN" "web-jsptaglibrary_1_1.dtd">
<!—- Опиcание библиотеки тегов —>
•
<taglib>
•
<tlibversion>1.0</tlibversion>
•
<jspversion>1.1</jspversion>
•
<shortname>namelib</shortname>
•
<uri></uri>
•
<info>Tag library для поддержки EJB </info>
•
<!— ejb tag —>
•
<tag>
•
<name>ejb</name>
•
<tagclass>taglib.EjbTag</tagclass>
•
<teiclass>taglib.EjbExtraInfo</teiclass>
•
<bodycontent>JSP</bodycontent>
•
<info>Обеспечивает вызов EJB из JSP</info>
•
<attribute>
•
<name>jndiName</name>
•
<required>true</required>
•
<rtexprvalue>true</rtexprvalue>
•
<type>String</type>
•
</attribute>
•
• <attribute>
•
<name>homeInterface</name>
•
<required>true</required>
•
</attribute>
•
<attribute>
•
<name>homeVar</name>
•
<required>true</required>
•
</attribute>
•
</tag>
•
</taglib>
Первые две стоки являются обязательным для любого XML-доку-
мента и называются прологом. Третья и последняя, тридцатая строки
определяют сам документ. Четвертая строка также является обязательной, содержит короткое имя, которое, возможно, будет использоваться
как prefix в директиве taglib. Пятая строка добавочная, определяет номер версии JSP. В шестой строке указывается имя, ассоциированное с
библиотекой тегов. С девятой строки начинается описание самого тега.
Имя тега, указанное в десятой строке, будет в дальнейшем использоваться при обращении к тегу из JSP. Данный параметр является обязательным, так же как tagclass, в одиннадцатой строке, указывающей полное имя класса, реализующего тег. Двенадцатая строка определяет добавочный класс, â котором описаны скриптовые элементы,
используемые тегом. Если таковые не используются, то строку можно
не описывать. Скриптовые элементы очень похожи на встроенные переменные JSP, т. е. их не надо специально создавать. Следующая <bodycontent>JSP</bodycontent>, тринадцатая строка необходима для опи-

134 Часть 2 Java Server Page
сания тела тега, может иметь три значения: tagdependent, JSP и empty.
Значение empty указывает на отсутствие тела у тега. Значение JSP
указывает на наличие в теле тега скриплетов, HTML-тегов, других тегов, пользовательских или основных. Все остальные типы, используемые в теле тега, указывают на значение tegdependent. Если данная
строка отсутствует, по умолчанию устанавливается значение jsp. Для
определения действий тег существуют атрибуты, строки с 15-28. В примере строки пятнадцатая, двадцатая, двадцать первая, двадцать четвертая, двадцать пятая, двадцать восьмая определяют три атрибута тега с именами jndiName — шестнадцатая строка, homeInterface — строка двадцать два и homeVar — строка двадцать шесть. Параметры
<required> в каждом атрибуте указывают, может ли данный атрибут
использоваться JSP-страницей. Значение true позволяет использовать
данный атрибут. Значение false определяет данный атрибут как добавочный, и его JSP проигнорирует при трансляции. В строке восемнадцать, <rtexprvalue>true</rtexprvalue>, содержится указание на возможность получить значения атрибута, используя динамическое выражение. Значение ïî умолчанию false íå позволяет присваивать
атрибуту результат выражения.
Сам тег является обычным Java-приложением и поэтому должен
следовать всем правилам Java. Класс создаваемого тега должен наследовать один из двух интерфейсов: пакета javax.servlet.jsp.tagext.Tag и
javax.servlet.jsp.tagext. BodyTag определяет два вида тегов с пустым телом тега (empty-body teg), в котором отсутствуют передаваемые атрибуты и тег, у которого атрибуты присутствуют.
1. package taglib;
2. import javax.rmi.PortableRemoteObject;
3. import javax.naming.*;
4. import javax.servlet.jsp.*;
5. import javax.servlet.jsp.tagext.*;
6. public class EjbTag extends BodyTagSupport {
7. private String jndiName = null;
8. private String homeVar = null;
9. private String homeInterface = null;
10. public EjbTag() {
11. super();}
12. public void setJndiName(String jndiName) {
13. this.jndiName = jndiName;}
14. public void setHomeVar(String homeVar) {
15. this.homeVar = homeVar;}
16. public void setHomeInterface(String homeInterface) {
17. this.homeInterface = homeInterface;}
18. public void doInitBody() throws JspException {
19. try {InitialContext ic = new InitialContext();
20. Object homeRef = ic.lookup(jndiName);
21. homeRef = PortableRemoteObject.narrow(homeRef, Class.forName
(homeInterface));
22. pageContext.setAttribute(homeVar, homeRef);}

Часть 2 Java Server Page 135
23. catch (NamingException ex) {
24. ex.printStackTrace();
25. throw new JspTagException("Unable to lookup home: "+jndiName);
26. } catch (ClassNotFoundException ex) {
27. ex.printStackTrace();
28. throw new JspTagException("Class "+homeInterface+" not found"); }}
При вызове страницы, содержащей JSP пользовательские теги, jsp-
engine вызывает методы, наследованные от двух вышеуказанных интерфейсов. Для получения информации об окружении, в котором будет
выполняться данный тег, используются методы setParent() и setPageContext(). Два этих метода не задействованы в обработке созданного тега, используются лишь для получения системной информации, необходимой для выполнения тега.
В первой строке указывается имя пакета в котором будут описаны
создаваемые теги. Именно это имя будет позже указываться в полном
имени тега, как первый префикс <taglib:ejb>. Операторы импортирования, указанные в строках со второй по пятую, являются стандартными
и определяют классы, необходимые для создания пользовательского тега. Для придания большей функциональности можно импортировать и
другие необходимые классы. В шестой строке указывается сам класс
тега, наследующего свои свойства от основного класса BodyTegSupport,
указывающего на наличие атрибутов в теле тега. Далее указываются
три поля-переменных. Строки десять, одиннадцать содержат конструктор и вызов использования глобального метода. Для тега, имеющего собственные атрибуты, необходимо создать методы set/get, по аналогии с
методами bean, описывающий данные аттрибуты. Обычно для этого используется шаблон метода setXXX()/getXXX(). Если определяется атрибут, например: с имеем JndiName в файле конфигурации тега, то в
теле исполняемого кода должны существовать пары методов setJndiName() getJndiName(), т. е. точно с таким же именем. Как и указано в примере, такими методами являются: setJndiName (String jndiName), setHomeVar(String homeVar), setHomeInterface (String homeInterface),
строки соответственно двенадцать, четырнадцать, шестнадцать и их эквиваленты строки шестнадцать, двадцать два, двадцать шесть в файле
конфигурации. Jsp-engine вызывает методы setXXX(), до непосредственного вызова основного метода doStartTag(). Для инициализации каких-либо внешних переменных можно воспользоваться методом doInitBody(), что и описано в строке восемнадцать. Два этих метода отвечают
за жизненный цикл создаваемого тега, т. е. они должны быть реализованы в теле тега. Все нижеперечисленные строки необходимы для работы с EJB session bean. В девятнадцатой строке используется, создается
объект класса InitialContext из пакета javax.naming. Экземпляр данного
класса используется для получения параметров инициализации исполняемого bean., строка двадцать, содержит объект, ассоциированный с
компонентом JndiNae, являющийся инициализационным параметром.
И наконец, в двадцать первой строке определяется еще один метод
EJB, принадлежащий session bean. Работа с EJB будет рассмотрена ниже. Как можно заметить, здесь описан только сам тег. EJB, вызываемые

136 Часть 2 Java Server Page
с помощью этого тега, необходимо создавать отдельно. При отсутствии
какого-либо из параметров вызываются исключительные ситуации
JspTagException — строки двадцать пять, двадцать восемь.
Можно рассмотреть еще один маленький пример — тег, определяю-
щий размер файла. Описание библиотеки тегов будет опущено за ненадобностью.
1. <?xml version="1.0" encoding="ISO-8859-1" ?>
2. <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD
JSP Tag Library 1.1//EN"
3. "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
4. <taglib>
5. <tlibversion>1.0</tlibversion>
6. <jspversion>1.1</jspversion>
7. <shortname>examples</shortname>
8. <uri>somewhere.com/taglib</uri>
9. <info>An example tag library</info>
10. <tag>
11. <name>size</name>
12. <tagclass>SizeTag</tagclass>
13. <attribute>
14. <name>uri</name>
15. <required>true</required>
16. <rtexprvalue>false</rtexprvalue>
17. </attribute>
18. </tag>
19. </taglib>
Все остальные атрибуты описаны выше и не требуют комментариев.
Само тело тега выглядит следующим образом:
1. package examples;
2. import java.io.*;
3. import javax.servlet.jsp.*;
4. import javax.servlet.jsp.tagext.*;
5. public class SizeTag extends TagSupport {
6. private String uri;
7. public int doStartTag() throws JspException {
8. StringBuffer sb = new StringBuffer();
9. String realPath = pageCotext.getServletContext().getRealPath(uri);
10. File f = new File(realPath);
11. length fileLength = f.length();
12. sb.append(fileLength);
13. sb.append(" bytes");
14. return EVAL_BODY_INCLUDE; }
15. public void setUri(String s) {
16. this.uri = s; } }
JSP-страница, использующая созданный тег:
<HTML>

Часть 2 Java Server Page 137
<HEAD>
<%@ taglib uri="http://SOMEWHERE.com/taglib" prefix="examples" %>
</HEAD>
<BODY>
The file is <examples:size uri="/jsp/index.html"/>.
</BODY>
</HTML>
Указанный пример достаточно простой все, так некоторые строки
можно прокомментировать. Во-первых, в шестой строке файла описания тега содержится новый элемент <uri> — значением которого является путь к библиотеке тегов. Именно этот элемент позже будет использован при вызове библиотеки из тега taglib. Создаваемый класс тега
расширен от класса TagSupport. В самом теле тега описаны два метода — doStartTag() и setUri().
Глава 17. XML и JSP
Основанный на теговой структуре JSP прекрасно подходит для создания XML-приложений. Универсальность XML позволила на его
основе строить конфигурационные файлы для многих приложений.
К сожалению, только последняя версия 1.1 JSP поддерживает DTD (Document Type Definition). Роли XML в JSP различны и многообразны.
Документ XML можно использовать как внешний источник информации или преобразовывать XML-элементы и работать с ними. XML создавался как язык для формирования единой формы документа, независимо от программного обеспечения, в котором создавался сам документ. Это позволило использовать XML êàê åùå один источник
информации, используемый в Web-приложениях. Единая структура
JSP, HTML и XML т. е. теговая структура представления данных, делает понятным JSP для сторонних разработчиков, не участвовавших в создании приложения.
Совершенно новая технология eXtensible Stylesheet Language Transformations (XSLT), предназначенная для трансформации стилевых таблиц XML-документа, также прекрасно работает с JSP. Теперь в одном
JSP-файле могут содержаться HTML-теги, Java-конструкции и таблицы стилей XSL для XML-документа. XSLT предназначена для создания
различных типов текстовых документов, HTML, PDF и конечно же
XML на основе XML-данных.
Модель XML-приложения, использующего JSP через призму MVC,
выглядит следующим образом:
Model: XML документ
View: XSL stylesheet
Controller: Java, JSP
Роль XML тегов в JSP такая же как и у JSP тегов в документе XML.
Что будет использовать программист — XML или JSP, зависит от конкретного приложения.

138 Часть 2 Java Server Page
JSP содержит данные двух типов: статические HTML-формы и
сформированные на основе клиентского запроса динамические данные.
Именно эти две способности JSP значительно упрощают совместное использование в одном приложении XML и JSP.
Взаимодействие между JSP и XML осуществляется в двух направлениях: JSP использует XML-элементы, или XML-документ содержит
аналоги JSP-инструкций. Так же как и JSP, документ XML имеет два вида тегов. Пустой тег, не имеющий тела, и хорошо оформленный тег (wellformed tag), имеющий тело. Для работы с XML-документами фирма SUN
поставляет пакеты классов com.sun.xml или javax.xml.parser. Данные пакеты распространяются отдельно и для их установки после локального
копирования требуется изменить системную переменную CLASSPATH.
Фирма IBM дополнила свой программный продукт VisualAge пакетами
com.ibm.xml собственной разработки по работе с XML-документами.
Воспользоваться данными классами можно для трансформации
XML-документа. Первый способ использования JSP-элементов, тегов
или bean заключается в использовании для парсинга (проверки) XMLдокумента и генерации на его основе HTML-документа или разборки и
сохранения XML-данных в других источниках. Следующий способ состоит в формировании нового XML-документа на основе входящего.
Как обычно, можно создать JSP тег, обрабатывающий документ или
установить bean в JSP-странице. JSP можно применять не только для генерации HTML-страниц, но и для XML-документа, это еще одно большое
преимущество JSP. Для генерации обычного XML-документа в JSP используется директива <%@ page ContentType("text/xml")%> или же используется ее аналог, использование метода setContent(), объекта response.
Кроме формирования XML-документа страницей JSP, сам XML-документ может содержать JSP-конструкции.
Например, скриплет в XML-форме имеет следующий вид:
<jsp:scriptlet>
Java-êîä
</jsp:scriptlet>.
Указание JSP-декларации имеет следующую конструкцию:
<jsp:declaration>
Java-êîä
</jsp:declaration>.
Очень похожая конструкция используется для JSP-выражений:
<jsp:expression>
Выражение
</jsp:expression>.
Для всех элементов JSP в XML можно создать аналогичный тег.
Проиллюстрировать использование XML-тегов, аналогов JSP можно
на следующем примере:
•
<jsp:directive.include file="RRLABS.com\hello.jsp"\>.
•
<?xml version="1.0" ?>

Часть 2 Java Server Page 139
<H1>Time JSP</H1>
•
<jsp:scriptlet>
•
java.util.Date _d = new java.util.Date(System.currentTimeMillis() );
•
</jsp:scriptlet>
•
<jsp:expr>dt.getHours()</jsp:expr>:
•
<jsp:expr>dt.getMinutes()</jsp:expr>:
•
<jsp:expr>dt.getSeconds()</jsp:expr>
•
Как обычно, начнем с первой строки, в котрой указан аналог уже известной JSP-конструкции, а точнее, директивы include, с указания пути
файла. Пролог XML, вторая строка, стандартная «шапка», XML-документа. Строки с четвертой по шестой, заменяют JSP-элементы <% %>,
определяющие начало и окончание скриплета. Последующие строки
просто выводят значения времени в разных единицах и являются аналогом JSP expression.
Поскольку количество клиентов, используемых в Web-приложениях
достаточно велико и они не обладают единой формой отображения информации, то рождается вопрос о том, как для различных Web-клиентов на основе одного источника данных, в данном случае XML документа, создать выходящий поток, понятный всем.
Во-первых, для каждого типа клиентов можно генерировать собственную JSP-страницу со своими специфическими тегами парсинга XML-документа и транслятора стилевых таблиц. Или же создать единую страницу, содержащую в виде bean или тега транслятор и парсер, которая генерирует различные типы выходных данных. Выбор подхода связан
решением о том, какие данные будут обрабатываться в JSP-элементе.
При широком распространении XML фирма IBM выпустила свои пакеты, дополняющие стандартную спецификацию XML. Классы по работе с XML-документами распространяются в jar-архиве — XML4J.JAR.
Для новой XML API версии 2.0 IBM изменила свои старые пакеты,
дополнив их классами по работе с SAX.
•
Для работы с XML-документом версии 2.0 используются следующие классы:
com.ibm.xml.parsers.SAXParser — описывает синтаксический анализатор SAX;
com.ibm.xml.parsers.ValidatingSAXParser — синтаксический анализатор;
com.ibm.xml.parsers.NonValidatingDOMParser — синтаксический
анализатор структуры документа DOM;
com.ibm.xml.parsers.DOMParser — сиснтакисческий анализатор DOM
•
При использования XML версиии 1.1 используется еще один класс:
com.ibm.xml.parser.Parser.
Использование JSP в Web-приложениях не ограничивается только
работой с HTML-тегами и XML-документами. Создание динамических
страниц, работа с графикой, использование swing-компонентов вот не
полный перечень использования JSP-технологии. И дальнейшее развитие Web-приложений отложит свой отпечаток на развитие JSP. На настоящий момент JSP солидный инструмент для решения задач e-commerse.

ЧАСТЬ 3 СЕРВЕРНЫЕ JAVA-КОМПОНЕНТЫ SERVLET
Как и большинство Web-компонентов, созданных с помощью Java,
servlet является Java-объектом, серверным объектом, точнее, Javaклассом, использующим Servlet API. Само название servlet говорит о
месте исполнения этого Java-объекта. По аналогии с applet servlet —
общее имя программ, написанных на Java и выполняющихся на сервере. В отличие от апплета, выполняющегося в среде браузера, servlet работает на сервере и требует наличия специальной программы-обработчика, называемой servlet engine, которая работает на Web-сервере. Servlet-engine обработчик запросов для различных servlets, JSP-файлов, и
других типов серверных приложений, написанных на Java. Servlet engine создает servlet переменные, загружает и выгружает servlets, обрабатывает запросы и генерирует ответы для клиента.
Servlet является обычным Java-классом, основной ролью которого
является обработка клиентских запросов. В отличие от обычных Javaприложений, JavaBean и апплетов, для запуска servlet требуется не
только JVM, но некоторые добавочные модули, протоколы передачи,
уже упомянутый servlet engine и непосредственно сам Java-совместимый сервер, на котором исполняется servlet.
Servlet является отличной альтернативой для замены стандартных
CGI-скриптов, выполняющих львиную долю работы по обработке Webзапросов пользователей. Servlets работают исключительно на сервере и
служат для построения Web-страниц «на лету», в момент исполнения.
Использование данной технологии создания Web-страниц «на лету»
имеет ряд определенных преимуществ. Скорость выполнения servlet в
4—10 раз быстрее аналогичных CGI-скриптов.
С помощью servlet можно создавать динамические Web-страницы,
обеспечивать доступ к базам данных и другим ресурсам, управлять
клиентскими запросами во время выполнения, фильтровать данные и
управлять одновременно несколькими клиентскими запросами и т. д.
Web-страница формируется на основе запрашиваемых данных, посланных на сервер клиентом. Все течет, все изменяется. И данные тоже периодически меняются, а значит, и должны отображаться динамически.
Servlet предназначен для формирования динамических HTML-страниц,
не важно, с какой периодичностью ресурсы обновляются. Кроме того,
данные могут находиться совершенно в разных источниках и иметь
разный формат представления, и опять servlet придет на помощь.
Безопасность, обеспечиваемая servlet, значительно более мощная,
чем стандартные способы, реализуемые через CGI-скрипты. Расширен-
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
