Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

JAVA. Серверные приложения

.pdf
Скачиваний:
0
Добавлен:
06.09.2026
Размер:
2 Мб
Скачать
Часть 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,
имеет дополнительные методы обработки текста, находящегося между открывающими и закрывающими элементами тега. Как и атрибуты обычного тега, этим атрибутам может присваиваться некое значение, результатом присвоения и будет являться значение атрибута <teg­lib: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, работающего с базой данных (первый оператор im­port). В третьей строке создается класс тега, расширенный от класса 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, т. е. их не надо специально создавать. Следующая <body­content>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() и setPage­Context(). Два этих метода не задействованы в обработке созданного те­га, используются лишь для получения системной информации, необхо­димой для выполнения тега.
В первой строке указывается имя пакета в котором будут описаны
создаваемые теги. Именно это имя будет позже указываться в полном имени тега, как первый префикс <taglib:ejb>. Операторы импортирова­ния, указанные в строках со второй по пятую, являются стандартными и определяют классы, необходимые для создания пользовательского те­га. Для придания большей функциональности можно импортировать и другие необходимые классы. В шестой строке указывается сам класс тега, наследующего свои свойства от основного класса BodyTegSupport, указывающего на наличие атрибутов в теле тега. Далее указываются три поля-переменных. Строки десять, одиннадцать содержат конструк­тор и вызов использования глобального метода. Для тега, имеющего соб­ственные атрибуты, необходимо создать методы set/get, по аналогии с методами bean, описывающий данные аттрибуты. Обычно для этого ис­пользуется шаблон метода setXXX()/getXXX(). Если определяется ат­рибут, например: с имеем JndiName в файле конфигурации тега, то в теле исполняемого кода должны существовать пары методов setJndiNa­me() getJndiName(), т. е. точно с таким же именем. Как и указано в при­мере, такими методами являются: setJndiName (String jndiName), set­HomeVar(String homeVar), setHomeInterface (String homeInterface), строки соответственно двенадцать, четырнадцать, шестнадцать и их эк­виваленты строки шестнадцать, двадцать два, двадцать шесть в файле конфигурации. Jsp-engine вызывает методы setXXX(), до непосредст­венного вызова основного метода doStartTag(). Для инициализации ка­ких-либо внешних переменных можно воспользоваться методом doInit­Body(), что и описано в строке восемнадцать. Два этих метода отвечают за жизненный цикл создаваемого тега, т. е. они должны быть реализо­ваны в теле тега. Все нижеперечисленные строки необходимы для рабо­ты с 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 (Do­cument Type Definition). Роли XML в JSP различны и многообразны. Документ XML можно использовать как внешний источник информа­ции или преобразовывать XML-элементы и работать с ними. XML со­здавался как язык для формирования единой формы документа, неза­висимо от программного обеспечения, в котором создавался сам доку­мент. Это позволило использовать XML êàê åùå один источник информации, используемый в Web-приложениях. Единая структура JSP, HTML и XML т. е. теговая структура представления данных, дела­ет понятным JSP для сторонних разработчиков, не участвовавших в со­здании приложения.
Совершенно новая технология eXtensible Stylesheet Language Trans­formations (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 имеет два ви­да тегов. Пустой тег, не имеющий тела, и хорошо оформленный тег (well­formed 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-com­merse.
ЧАСТЬ 3 СЕРВЕРНЫЕ JAVA-КОМПОНЕНТЫ SERVLET
Как и большинство Web-компонентов, созданных с помощью Java,
servlet является Java-объектом, серверным объектом, точнее, Java­классом, использующим Servlet API. Само название servlet говорит о месте исполнения этого Java-объекта. По аналогии с applet servlet — общее имя программ, написанных на Java и выполняющихся на серве­ре. В отличие от апплета, выполняющегося в среде браузера, servlet ра­ботает на сервере и требует наличия специальной программы-обработ­чика, называемой servlet engine, которая работает на Web-сервере. Ser­vlet-engine обработчик запросов для различных servlets, JSP-файлов, и других типов серверных приложений, написанных на Java. Servlet engi­ne создает 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-скрипты. Расширен-