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

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

.pdf
Скачиваний:
0
Добавлен:
06.09.2026
Размер:
2 Мб
Скачать
Часть 2 Java Server Page 91
Глава 8. Как работает JSP
В самом названии Java Server Page (JSP) скрыто место выполнения данных страниц-сервер. Работа JSP происходит на сервере на среднем, втором, уровне многозвенной Web-архитектуры. Как и всякое серверное приложение, JSP имеет собственный сценарий обработки запросов представленный на рис. 2.1:
Web-браузер или другой клиент посылает запрос на JSP-страни­цу Web-сервера используя либо HTML-теги, либо указывая адрес JSP-страницы. О способах доступа к JSP-странице можно узнать в следующей главе. Далее JSP-обработчик (engine) проверяет содер­жимое JSP-файла, выделяя отдельно Java-код и HTML-элементы. Затем транслирует страницу во «временное» приложение (servlet), содержащее статические данные и HTML-элементы. При необходи­мости можно указать дополнительные операции, выполняемые транслятором при проверке JSP-страницы. Для данной операции в JSP используются специальные указания или директивы, описанные в главе 10.
После проверки временное приложение (servlet) компилируется стандартным Javaс-компилятором в исполняемый Java .class байт код, порожденный от javax.servlet.jsp.JspPage.
Временное приложение (servlet) проходит свой жизненный цикл. В методе init() и в своем основном методе service() servlet обрабатыва­ет клиентский запрос, генерирует объект response, содержащий необ­ходимые HTML-элементы, и посылается клиенту. Временное приложе­ние-servlet, созданное на базе JSP, имеет свои методы жизненного цикла, аналогичные методам стандартного servlet. Основной метод, об­рабатывающий клиентский запрос _jspService(), является полным ана­логом метода service(), стандартного servlet. В отличие от других мето­дов жизненного цикла, основной метод не может быть перегружен. Единственное, что может сделать разработчик, так это перегрузить методы, предназначенные для инициализации, метод jspInit() и метод
Рис. 2.1. Механизм работы JSP
92 Часть 2 Java Server Page
удаления jspDestroy() временного приложения из системного окруже­ния Web-сервера. Насколько велика в этом надобность? У автора та­ких потребностей не возникало. Более подробную информацию о serv­let можно найти в третьей части книги, посвященной servlet.
Все операции по трансляции для клиента невидимы, более того, эти операции практически не занимают времени клиентского ожидания, все операции трансляции выполняются на сервере в многопоточном режи­ме, поэтому практически не влияют на время отклика.
Глава 9. Вызов JSP
Хороший ресурс — это достигаемый ресурс. Что толку в сетевом ре­сурсе, если к нему нельзя обратиться. JSP-серверная технология, но об­ращение к серверу не подразумевает обращение прямо к искомому ре­сурсу. Чтобы достучаться до серверного ресурса, ресурс необходимо как-то конкретизировать в клиентском запросе. По имени ли, или по адресу, или еще по каким признакам.
Обращение к JSP клиент может осуществлять нескольким способами: непосредственно через указание URL, из servlet или же из HTML-стра­ницы:
Самый распространенный способ получить доступ к JSP-странице
это непосредственно указать адрес JSP-страницы. Адрес в Интер­нет — Uniform Resource Locator (URL) состоит из нескольких основных частей, а именно первым указывается протокол передачи данных, затем доменное имя сервера и сам ресурс. Клиент в брау­зере указывает целевой ресурс, в данном случае JSP-страница, в этом случае HTML-страница, видимая пользователем, будет сгене-
рирована JSP. http://www.rrlabs.com/index.jsp В большинстве случаев запрос к JSP поступает с HTML-страницы,
посещенной клиентом. Вышеуказанный способ обращения к JSP явля­ется самым простым и самым распространенным. При его использова­нии отсутствует необходимость создавать первичные HTML-страницы и организовывать доступ через теги HTML.
Указание адреса— способ замечательный, но пользователь не всег-
да может точно указать URL, в большинстве случаев клиенту это-
го и не надо. Для обращения к внутренним ресурсам или находя-
щимся на другом сервере существует способ указания ресурса не-
посредственно в HTML. Доступ к ресурсам в HTML можно
организовать с помощью линков, либо так называемых «якорей»,
либо используя специальный HTML тег FORM, предназначенный
для передачи по определенному способу. Использование линка
очень похоже на вышеуказанный способ обращения к JSP. Исполь-
зование тега FORM предназначено только при формировании
определенного условия, например, при нажатии на кнопку клиент
переходит на другой ресурс, страницу. Запрос от браузера клиен-
та, посылаемый на Web-сервер, указывает на определенную
Часть 2 Java Server Page 93
HTML-страницу, содержащую ссылку на JSP. Обращение возмож-
но с использованием HTML-формы : <FORM>:
<FORM METHOD="POST|GET" ACTION="samplepost.jsp">
<!— какие-либо операторы, если надо —>
</FORM>
Организация доступа к JSP не ограничивается использованием тега
FORM. «Якорь» внутренний элемент HTML-страницы — предназначен для связывания в источнике ссылок на другие ресурсы. Использование подобного способа заключается в использовании HTML-«якоря»:
<A HREF="www.rrlabs.com/hello.jsp"> URL jsp</a>
«Якорь» используется при без условном переходе, т. е. действие
клиента ограничены только щелчком на элементе, содержащем ги­перссылку.
Более подробную информацию о создании HTML-стоаниц и связыва-
нии различных источников при помощи HTML-элементов можно найти в любом руководстве, посвященном программированию Web-страниц.
Но динамические страницы потому и динамические, что часть зна-
чений вычисляется во время исполнения страницы. Вызов JSP
можно осуществлять и из других источников, в частности исполь-
зуя методы серверных Java-программ — servlet. Вызов из servlet
осуществляется при помощи специальных методов. Первый способ заключается в использовании метода sendRedirect()
объекта response, которому в качестве аргумента передается значение url ресурса:
import javax.servlet.http.*; public class DateDi playServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws javax.servlet.ServletException, java.io.IOException { resp. sendRedirect("/index.jsp");
О servlet будет сказано ниже, данный пример просто иллюстрирует
использование метода sendRedirect(). При обращении к ресурсу servlet отобразит в браузере клиента HTML-страницу, сгенерированную фай­лом Index.jsp.
Альтернативный способ вызова JSP, применяемый в servlet, заклю-
чается в использовании внутреннего объекта RequestDispatcher, описы­вающего системное окружение выполняемого servlet:
import javax.servlet.http.*; public class DateDisplayServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws javax.servlet.ServletException, java.io.IOException { getServletContext().getRequestDispatcher("/filename jsp").forward(req,resp);}
94 Часть 2 Java Server Page
Как и пример описанный выше, здесь просто описывается servlet,
перенаправляющий клиентский запрос в файл filename.jsp.
Более побробную информацию о работе servlet можно получить из
главы, посвященной servlet.
В новой спецификации JSP описаны встроенные теги, предлагаю-
щие работу с внешним (по отношению к запрошенному) ресурсом.
Только при использовании версии JSP 1.0 и выше можно восполь-
зоваться встроенными тегами <jsp:forward>и <jsp:include>. Дан-
ные теги являются аналогами методов, используемых в servlet для
организации доступа к потусторонним источникам. Тег <jsp:for-
ward> предназначен для перенаправления клиентского запроса, а
тег <jsp:include> для включения данных из других источников.
Оба тега и работа с ними описаны в главе 11, посвященной JSP те-
гам. В отличие от динамических данных, включаемых в JSP с по-
мощью тега <jsp:include>, статические данные добавляются в JSP-
страницу использованием директивы <%@ include %>, но здесь
речь идет именно о включении в исполняемую страницу програм-
много кода файла, указанного в директиве <%@ include%>.
Все способы обращения к JSP, применяемые в HTML, также при-
менимы и самой JSP, поскольку та сама является расширенной ча-
стью HTML. Номинально существуют и другие способы обращения к JSP, исполь-
зуя конструкции скриптовых языков или серверных программ. Каждый язык программирования, используемый в Web, по-своему организует доступ к внешнему ресурсу, коим является JSP. Рассматривать в рам­ках одной книги каждый из способов не представляется возможным.
Глава 10. Основные JSP-компоненты
Основными объектами, с которыми работает JSP, являются скрипле-
ты (отрывки кода, написанные на языке Java), встроенные теги и Java­Bean. Эта великолепная тройка имеет одного отца и трех разных мате­рей. Все объекты реализованы с помощью языка Java, но представляют из себя различные Java-компоненты.
Первые скриплеты — дети безответственной матери, они просто со-
держат «отцовский» код, но зато они самые распространенные, и имен­но скриплеты делают основную работу в JSP. Благодаря скриплетам HTML превращается из статического материала в динамическую кар­тину. Более ответственные матери укутывают детей перед прогулкой и кормят завтраками. Теги — это пользовательские программы, написан­ные на Java, и имеют атрибуты. В отличие от своих братьев скриплетов, теги представляют из себя готовые приложения и с некоторыми по­правкам в паспорте (конфигурационном файле) могут свободно переме­щаться из одного приложения в другое. JavaBean — «золотая моло­дежь», имеют все возможности к свободному перемещению, к самостоя­тельной жизни, сразу создаются как независимые приложения, и достучаться до них можно лишь двумя способами, если использовать
Часть 2 Java Server Page 95
Рис. 2.2. Основные Java-компоненты, используемые в JSP
методы getXXX()/setXXX() На рис. 2.2 изображены основные Java-ком­поненты, используемые в JSP-странице. Нельзя забывать о других ре­сурсах, располагающихся в JSP, таких, HTML-теги и графические изо­бражения.
Доступ к скриплетам в JSP-полный. Программист сам решает, как
реализовать то или иное решение. С тегами дело обстоит иначе. Поско­льку они представляют вполне законченное приложение, программисту необходимо узнать у разработчика тега, для каких целей используется тег и какими атрибутами описывается, или в крайнем случае самостоя­тельно, используя утилиту javap, просматривать код созданного тега и догадываться о происходящем. С JavaBean проблема та же, только обычно можно догадаться о части выполняемых задач, поскольку Java­Bean в большинстве случаев графическое приложение.
И те и другие вполне взаимозаменяемы, каждая операция может
быть описана любым способом — и тегом, и JavaBean, и обычным скриплетом — все зависит только от лени программиста. Первые два пасынка описаны ниже, ну а JavaBean — это отдельная технология, за­служивающая отдельного описания, а значит, здесь рассмотрена не бу­дет.
JSP перед обработкой клиентского запроса является обычным тек-
стовым файлом со специальными знаками разметки (более популярное название теги) и фрагментами кода на скриптовом языке. В случае с JSP таковым языком считается Java и используются HTML-теги. Файл JSP создается в любом текстовом редакторе или с помощью специаль­ного инструмента, такого, как IBM WEB Sphere Studio Page Designer, представляющий визуальные средства создания JSP, или же VisualAge for Java. Созданию JSP вышеуказанными средствами посвящено прило­жение А. Именование файла не имеет особых правил, но расширение его обязательно должно быть .jsp, указывающее на использование в данной странице Java-кода и JSP-конструкций. Как говорилось выше, создание JSP сводится только к написанию смешанного кода и разме­щению JSP на сервере, этап компилирования и трансляция созданного кода отсутствует. Каким файл JSP был создан, таким файл и будет представлен клиентскому запросу. Поэтому легче использовать специа-
96 Часть 2 Java Server Page
льные средства разработки, проверяющие валидность HTML-тегов, и проводящие синтаксический анализ на этапе создания приложения.
Если опустить описание HTML-тегов, они стандартны, и не занима-
ться введением в язык программирования Javа, то непосредственно JSP-конструкции можно разделить на два типа, о «золотой молодежи» говорить не будем.
В существующих версиях JSP описаны два типа JSP-конструкций,
встраиваемых в обычный HTML-файл: скриплеты и специальные JSP­теги. При совместной работе с XML-документом ограничения по испо­льзуемым тегам отсутствуют, поскольку все XML теги создаются само­стоятельно разработчиком.
10.1. Кодовые части JSP. Скриплеты <% scriplet %>
Скриплет — часть кода программы, написанного только на одном
языке. Здесь можно уловить некоторое созвучие с такими словами, как апплет и servlet. В этом нет ничего удивительного, так как JSP детище компании SUN, впрочем, как и другие технологии, описанные этой кни­ге. Скриплет состоит из фрагментов Java-кода и символов разметки — скриптовых элементов, размечающих создаваемый код по определен­ным правилам. Создание методов и переменных в скриплете должно со­ответствовать спецификации скриптового языка, в данном случае языка Java.
Все скриптовые элементы JSP начинаются со знака <%. Скриптовые
элементы помещаются в открывающиеся и закрывающиеся <% скрипт %> элементы. Скриптовые элементы включают в себя тело программы, написанное на языке Java. Таких тел в странице может быть несколько, они могут нести отдельную смысловую нагрузку или быть разделены между собой другими синтаксическими конструкциями. Код тела про­граммы должен следовать синтаксическим правилам используемого языка. В скриплете можно определять переменные и методы, а также использовать встроенные объекты. Все дополнительные синтаксические элементы, HTML-теги, JSP элементы и изображения, описываются за пределами скриплета. В JSP допускается разделение тела метода встроенными тегами и перенос переменных в другой файл, также допу­скается включение HTML-тегов в тела выражений и методов. Скрипле­ты можно размещать в любом месте JSP.
Очень простой пример JSP-файла содержащего наиболее часто испо-
льзуемые скриптовые элементы (HTML-теги и скриплет):
1. <HTML><TITLE>SIMPLE JSP </TITLE><BODY bgcolor= ="#ee34ee">
2. <% java.util.Date _date=new java.util.Date();
3. out.println("<B>Now </B>" +_date.toString()); %>
4. </BODY><HTML>
Первая (1) и четвертая (4) строки содержат обычные HTML-теги. Те-
ло скриплета начинается со второй (2) строки, в которой выделяется па-
Часть 2 Java Server Page 97
мять под новый объект _date, а в третьей (3) строке значение объекта выводится браузером в местном формате времени.
Данный пример прекрасно отражает основные правила формирова-
íèÿ скриплета. Âñå HTML-òåãè должны иметь закрывающуюся часть </>. Также каждый родительский тег должен закрываться по­сле закрытия всех дочерних тегов. А тело программы помещается между знакам <% %>, где, в отличие от HTML-тегов, отсутствует знак закрытия (/).
Все скриплеты являются частью основного метода service(), сгенери-
рованного servlet. Это значит, что скриплет выполняется в момент по­ступления запроса, а заканчивает свои действия после формирования выходящего потока.
При необходимости включения скриплетных знаков в тело Java-кода
их надо поместить в двойные кавычки "<%". Во всех существующих версиях определены три типа скриптовых элементов: <%!declarati­on %>, <%=expression %>, <% scriplet%>, кроме того, существует еще два типа синтаксических конструкций, применяемых в JSP.
Специальные теги похожи на обычные HTML или XML теги и дирек-
тивы, представляющие собой смесь скриплетов и специальных тегов. Оба типа будут рассмотрены ниже.
10.2. Определения переменных и методов. Декларации <%! declaration %>
Декларация методов или переменных осуществляется с использо-
ванием стандартного скриптового элемента и последующего восклица­тельного знака <%!. Декларации применяются при создании перемен­ных полей и методов, используемых в дальнейшей программе. Так же как в стандартной программе, написанной на Java, определению пере­меной предшествует указание класса. Но в отличие от приложения, переменные видимы только на той странице, на которой указаны. Го­воря языком программистов, область видимости, область действия, пе­ременных ограничивается область видимости созданного класса, если она не указана как глобальная переменная. Можно указать любое ко­личество переменных или методов в декларации, но использовать можно только те переменные и методы, которые уже описаны, (прин­цип любви — сначала предлагаем, потом занимаемся). В одной декла­рации можно указать несколько элементов, перечисленных через за­пятую, или же указать для каждого элемента собственную деклара­цию. Обязательно указание точки с запятой (;) в конце каждого декларированного оператора. Все остальные правила по определению операторов соответствуют правилам создания переменных и методов в Java. Декларативные элементы, описанные в одной JSP, могут легко взаимодействовать друг с другом. Если убрать формальности, то JSP можно представить как описание единого класса, со всеми вытекаю­щими последствиями. Еще раз по-китайски, область видимости объ­ектов созданного на основании JSP класса различна, поскольку вы­полняется в многопотоковом режиме. Поэтому данные необходимо
98 Часть 2 Java Server Page
синхронизировать. Есть другой способ избежать неприятностей: испо­льзование директивы <%@ page isThreadSafe="false" %>. По умолча­нию значение этой директивы всегда true. .т. е. если директива не указана в JSP, то сгенерированный servlet реализует интерфейс Sing­leThreadModel, т. е. работает в однопотоковом режиме. О servlet более подробно сказано в третьей части книги, а директивы JSP описаны ниже.
Методы и переменные, импортированные через директиву <%@ pa-
ge%>, нет необходимости помещать затем в декларативную конструк­цию. Использование декларирования методов и переменных оправдыва­ет себя тогда, когда код разделен на много маленьких частей или же разнесен на большие расстояния. Также возможно просто создать стра­ницу с некоторыми переменными и затем с помощью JSP тега <jsp:inc­lude> вызывать данную страницу по мере необходимости. Например:
1. <%! String _s = ("Hello!") ; %>
2. <%! java.util.Date _date = new java.util.Date(); %>
3. <% out.println("<B>NOW</B>"+_date.toLocaleString()+ _s ); %>
Первые две строки определяют некоторые переменные, одна из ко-
торых примитивного типа String, другая ссылочного типа Date. Если не­понятно, лучше посмотреть какое-либо руководство или спецификацию по языку программирования Java. Две переменные затем можно будет использовать в дальнейшем, для различных нужд, используя вышеука­занный тег. Только представьте себе, не надо везде писать импортное слово "Hello", а просто везде указывается краткое и лаконичное _s. В третьей строке оператор out, выполняющийся в отдельном потоке, устанавливает вышеуказанные переменные в выходящий поток для отображения клиентским браузером. Ключевое слово, ключевое, по­скольку оно зарезервировано для использования в JSP, а не в Java, т. е. им нельзя объявлять объекты, out является встроенным объектом, представляющим выходящий поток, не требующим инициализации, как это произошло с двумя переменными, указанными выше. Метод println() добавляет строку в HTML-страницу, содержащую слово NOW жирным шрифтом и дату в локальном формате времени. Встроенные переменные описаны чуть ниже в данной главе.
Не хочется полностью переключать внимание на другие темы, но ма-
ленькое отступление, думаю, простительно. Как уже говорилось выше, JSP после трансляции представляет временное приложение, называе­мое servlet. Каждый servlet проходит свой собственный жизненный цикл, первым этапом которого можно назвать метод инициализации servlet — метод init(). Так вот, декларации отлично подходят для созда­ния переменных в инциализационном методе servlet.
В отличие от обычных скриплетов, выполняющихся в основном мето-
де _jspService(), декларации выполняются как отдельные методы. Су­ществующие методы инициализации и удаления дают разработчику еще одну возможность тонкой настройки приложения. Обычной практи­кой считается размещение в инициализационных методах приложений кода, используемого единожды. Метод инициализации, у JSP метод
Часть 2 Java Server Page 99
jspInit(), вызывается один раз при создании экземпляра объекта. Декла­рация с участием метода инициализации выглядит следующим обра­зом:
<%! public void jspInit() { String name =" user"; Document _doc =new Document(); String dbDriver="COM.ibm.jdbc.net.DBDriver" parser( name);
}
%>
Метод деструкции необходим для освобождения ресурсов, занятых
исполняемым приложением. В нем выполняются операторы освобожде­ния и контроля занятых ресурсов, прежде чем приложение будет га­рантировано удалено из исполняемого окружения. Метод _jspService() является полным аналогом созвучного метода servlet и является основ­ным по обработке клиентского запроса.
10.3. Формирование выходящих данных. Выражения <%= expresion%>
Самый простой способ напечатать объект в Web-браузере клиента —
это использовать специальную JSP-конструкцию, называемую expressi­on (выражение).
Выражения в JSP предназначены для конвертации данных в выхо-
дящий поток, в строковые значения результатов выполняемых методов для отражения в клиентском браузере. Обычно выражения заменяют последовательность операторов <%out.print(anJavaObject.toString());%>.
Выражения можно использовать любом месте JSP-страницы, но не-
обходимо учесть, что методы и переменные, используемые в выраже­нии, должны обязательно следовать после объявления таковых в декла­ративных частях JSP.
Обычно JSP-выражения используются для единовременного выпол-
нения методов и отражения результатов в виде строковых значений. Методы и переменные, используемые в JSP-выражениях, могут быть как объектами установленного JavaBean в JSP или же определены в декларативной части JSP-страницы. При невозможности правильной конвертации данных в выражение генерируется исключительная ситуа­ция ClassCastException.
Все примитивные Java, типы такие, как short, int, и long, могут авто-
матически конвертироваться в строки. Классы, созданные программи­стом, могут реализовывать метод toString() для успешной конвертации в строковые значения.
В JSP-выражениях восклицательный знак у открывающегося тега
заменен на знак равенства.
1. <%! java.util.Date _date;%>.
2. <%= "today"+(new java.util.Date())%>.
100 Часть 2 Java Server Page
Пример очень похож на своего предшественника, за исключением
отсутствия встроенного объекта out и его метода println(). Но выходя­щий поток существует, это же выражение, и клиент в своем браузере увидит ту же самую дату.
Необходимо отметить отсутствие точки с запятой в конце выраже-
ния. Код, включенный в выражение, автоматически заменяется парой вышеуказанных операторов конвертации в строковое значение. В выра­жениях позволительны любые конструкции, допустимые в Java. Выра­жения предназначены для ускорения создания JSP-страниц и в боль­шей степени напоминают макросы, сразу выводящие в символьный по­ток результат действий.
10.4. Указания транслятору. JSP -ирективы
Директивы — это инструкции, которые должны быть выполнены
JSP engine в момент трансляции JSP-страницы в исполняемый класс, например, директивы для импортирования необходимых для выполне­ния классов. Директивы, встроенные в JSP, начинаются со знака ком­мерческого и (@), заключенного в скриптовые элементы <%@ и %>, полностью определение директивы выглядит следующим образом:
<%@ nameDirective attributes=value %>.
Каждая директива является преопределенной в спецификации, по-
льзователь не имеет права создавать собственные директивы, по край­ней мере в существующих версиях. Директива имеет собственное имя и атрибуты с определенными значениями.
В JSP существующие директивы выполняют несколько ролей. Неко-
торые предназначены для выполнения определенных действий, другие являются пред установками для jsp-engina. Директивы указывают тип используемого скриптового языка, с помощью которого создается JSP. Также с помощью директив описываются наследуемые классы и только в случае использования Java как скриптового языка. Наконец с помо­щью директив описывается MIME тип объекта сформированного для ответа. Дополнительно директивы могут указывать внешние источники, предназначенные для включения в исполняемую JSP. В последней вер­сии 1.1 определена еще одна директива, описывающая JSP-теги, со­зданные программистом самостоятельно.
В спецификациях 0.91 и 1.0 описаны два основных типа директив:
page, предназначенная для импортирования классов, необходимых для работы страницы, и реализованных интерфейсов; и include, предназна­ченная для включения в тело кода внешних файлов. Спецификация версии 1.0 не определяет еще одну директиву taglib, необходимую для определения пользовательских тегов, данная директива работает толь­ко с версией JSP 1.1. Подробнее о возможности поддержки пользовате­льских тегов можно узнать из документации на Web и\или сервер при­ложений или на основном сайте фирмы SUN: http://java.sun.com/pro­ducts/jsp.