Java Server Pages

Введение

Технология Java Server Pages (JSP) является составной частью единой технологии создания бизнес-приложений J2EE. JSP - это альтернативная методика разработки приложений, динамически генерирующих ответ на те или иные запросы клиента. Прежде чем JSP документ будет использован, специальная процедура преобразует его в соответствующий сервлет. В свою очередь, сервлет, как правило, пишется на языке Java и реализует определенный интерфейс. Далее, сервлет также не является самостоятельным приложением и функционирует, только будучи помещен в соответствующий web-контейнер. Web-контейнер обеспечивает обмен данными между сервлетом и клиентами, берет на себя выполнение таких функций, как создание программной среды для функционирующего сервлета, идентификацию и авторизацию клиентов, организацию сессии для каждого из них.

На настоящий момент реализована трансляция JSP страницы в сервлет, программный код которого пишется на языке Java. Однако авторы спецификации Java Server Pages оставляют возможность реализации JSP и на других языках программирования.

Соотношение между сервлетами бизнес-приложения и адресами URL на сервере задается в дескрипторе размещения. Технология реализации сервлетов обсуждается в отдельной статье. Сейчас же важно отметить тот факт, что программный код, используемый для написания сервлетов, не всегда удобен для динамической генерации текстовых документов в ответ на запрос клиента. Например, фрагмент сервлета, где осуществляется генерация динамической HTML страницы, может выглядеть следующим образом:
PrintWriter out = res.getWriter();
out.println(”“);
out.println(”“);

out.println(”“);
out.println(”“);
out.close();

Как видим, каждой строке HTML документа в сервлете соответствует определенный фрагмент программного кода, что не способствует простоте разработки и сопровождения бизнес-приложений.

Удобнее разделить динамическую и статическую части генерируемой web-страницы. Для создания динамической части по-прежнему будет использоваться Java или другой язык программирования. Статическую же часть имеет смысл оформить как текстовый документ - Java Server Page (JSP страницу), оформленную в соответствии с требованиями HTML, XML или другого стандарта разметки. Фактически, JSP страница можно рассматривать как шаблон или прообраз динамической страницы, которую остается дополнить динамическими элементами. Для описания динамической составляющей, в технологии JSP предусмотрено два основных механизма: компоненты JavaBean и библиотеки дополнительных тэгов. Как результат, технология JSP предполагает параллельную работу над приложением двух разных специалистов: программиста и ответственного за верстку документов (web мастера), которые отвечают, соответственно, за разработку динамической и статической частей документов, генерируемых в ответ на запросы клиентов.

Как уже говорилось, перед тем, как использовать JSP страницу, ее необходимо преобразовать в соответствующий сервлет. Такое преобразование может выполняться либо в момент, когда JSP страница помещается на сервер, либо когда клиент первый раз обращается к этой странице. Поскольку процедура преобразования довольно трудоемка и занимает много времени, то выполняется она обычно только один раз. Все же последующие обращения клиента к JSP странице сервер автоматически переадресует на сервлет, который был получен в результате ее преобразования.

Сервлет, полученный после преобразования JSP страницы, функционируют в рамках стандартного контейнера сервлетов и используют строго регламентированный интерфейс. Поэтому эта технология не зависит от каких-либо особенностей той или иной аппаратной платформы. С другой стороны, поскольку JSP технологии может строиться на базе интерпретируемого языка Java, то это дает гарантию портируемости приложений, построенных на технологии JSP, на любую платформу, где можно установить виртуальную Java машину.

JSP страница

Как правило, JSP страница хранится в отдельном файле с расширением .jsp. Большая часть содержимого JSP страницы преобразуется в сервлете в набор инструкций out.println(). Пример JSP страницы:
<%@ taglib uri="/exttags.tld" prefix="dscat" %>
<%@ page import = "xbcat.util.*" %>

All Customers




<%
Vector menu=pagescroll.getMenu();
if( pagescroll.page.size() > 0 ) {
%>

<%= pagescroll.getTotalPages() %> <% if(!pagescroll.isSinglePage()) {
for(int i=0; i String href = ((ScrollMenu)menu.elementAt(i)).m_Href;
String name = ((ScrollMenu)menu.elementAt(i)).m_Name;
if( href != null ) { %>

где, uri - абсолютный или относительный адрес URI, уникальным образом идентифицирующий дескриптор библиотеки тэгов, связанных с указанным префиксом. Указанный префикс используется для идентификации соответствующих custom тэгов.
<%@ taglib uri="http://www.mycorp/supertags" prefix="super" %>


Процедуру создания custom тэгов мы рассмотрим позднее.

Директива include. Используется для помещения в JSP страницу текстов и программного кода из других источников. Подстановка выполняется в момент, трансляции JSP страницы в соответствующий сервлет. Пример использования директивы:
<%@ include file="menu.jsp" %>

Заметим, что подстановка материалов из внешнего источника может выполняться также с помощью специального тэга , который будет рассмотрен нами позднее. Отличие данного тэга от описываемой директивы заключается в том, что подстановка осуществляется непосредственно в процессе обработки клиентского запроса, а потому может быть привязано к параметрам запроса.

Фрагмент программного кода на JSP странице (скрипт)

Скрипт, как и остальные элементы, привносит в конечный документ динамическую составляющую. Однако, в отличие от них, скрипт - программный код, помещенный непосредственно в текст JSP страницы. Скрипт может производить вычисления или манипулировать объектами, что позволяет наглядно связывать характеристики генерируемой страницы с параметрами запроса клиента и бизнес-правилами приложения. Элементы скриптов бывают трех типов: декларации, скриплеты и выражения.

Декларации

После преобразования JSP страницы в сервлет большая часть ее содержимого попадает в метод _jspService(), который вызывается всякий раз, когда появляется необходимость обработать заказ клиента. Декларация на JSP странице чаще всего используется для того, чтобы объявить дополнительные атрибуты и методы в классе сервлета, которые будут доступны при обработке любого запроса клиента. Декларации имеют синтаксис <%! ... %>.

Примеры деклараций на JSP странице:
<%! int i; %>
<%! int i = 0; %>
<%! public String f(int i) { ... } %>

Скриплеты

Скриплет может содержать программный код и декларации локальных переменных, которые будут использованы для обработки запросов клиентов. Фактически, скриплет - это фрагмент программного кода из будущего сервлета, который в свое время будет помещен в метод _jspService(). Являясь частью сервлета, скриплет получает доступ к объекту response и, соответственно, может самостоятельно формировать определенную часть конечной динамической страницы. Однако чаще всего скриплеты используются не для этого, а для того, чтобы управлять объектами бизнес-логики и логикой приложения.

Скриплет имеет синтаксис <% ... %>. Пример использования скриплетов в содержимом JSP страницы:
<% if (i == 0) { %>
Good morning
<% } else { %>
Good afternoon
<% } %>

Чтобы оценить наглядность и простоту этой конструкции, сравните ее с эквивалентным фрагментом программного кода в сервлете:
if (i == 0) {
out.println(”Good morning”);
} else {
out.println(”Good afternoon”);
}

Выражения

Часто страница, передаваемая клиенту, содержит результаты вычислений или обращений к тем или иным методам и атрибутам определенных классов. Любой из таких динамических элементов можно преобразовать в строку и представить на JSP странице с помощью вызова out.println в соответствующем скриплете:
<% UserProfile user = (UserProfile) session.getValue("Profile"); %>
<% out.println(user.getFaxNumber()); %>

Вторую строку в приведенном примере удобнее и нагляднее представить в боле кратном виде, используя синтаксис выражения <%= ... %>:
<%= user.getFaxNumber() %>

Другой пример использования выражения в теле JSP страницы:
<%! int i = 0; %>
Hi, now the servlet processing <%= ++i %>th request.

JSP страницы и объекты

В ходе обработки запросов, JSP страница может получать доступ к объектам, расположенным на сервере, создавать их и модифицировать. Доступ к объектам осуществляется через элементы скриптов и action. Каждый создаваемый в приложении объект имеет определенное время существования, которое декларируется в соответствующем атрибуте. Спецификацией предусматривается четыре интервала:

page - Объект, чье время существования определяется как page, доступен в пределах только той JSP страницы, где он был создан. Все ссылки на этот объект должны быть освобождены сразу же после того, как запрос клиента был обработан.
request - Объект, чье время существования определяется как request, доступен для всех страниц, связанных с обработкой данного запроса. В частности, если имеет место переадресация обработки на новую JSP страницу, данный объект будет доступен и на прежней, и на новой странице. Как и в предыдущем случае, ссылки на объект после обработки запроса должны быть освобождены.
session - Объект с областью видимости session доступен для всех страниц, обрабатывающих запросы, связанные с определенной сессией (сеансом связи с конкретным клиентом). Ссылки на объекты, связанные с сессией, помещаются в объект session. По окончании сеанса связи ссылки должны быть освобождены.
application - Наиболее общая область видимости. Объекты, имеющие область существования application, не привязаны к какой-либо отдельной странице или сеансу связи и доступны со всех JSP страниц данного приложения.

JSP страница всегда имеет доступ к определенному набору объектов, создаваемых web контейнером по умолчанию:

request - Объект, содержащий запрос клиента. Относится к классу javax.servlet.ServletRequest или другому наследующему его классу. Например, для протокола HTTP это будет объект класса javax.servlet.http.HttpServletRequest. Область видимости объекта - request.
response - Объект, в который сервлет будет помещать ответ на запрос пользователя. Относится к классу javax.servlet.ServletResponse или другому наследующему его классу. Например, для протокола HTTP это будет объект класса javax.servlet.http.HttpServletResponse. Область видимости объекта - request.
pageContext - Объект, определяющий контекст JSP страницы. Область видимости объекта - page
session - Объект, создаваемый контейнером для идентификации клиента, а также хранения персональных объектов. Создается контейнером для протокола HTTP и является экземпляром класса javax.servlet.http.HttpSession.
application - Объект, связанный с конфигурацией сервлета, соответствующего данной JSP странице. Область видимости объекта - application.
out - Объект, содержащий выходной поток сервлета. Информация, посылаемая в этот поток, будет передана клиенту. Объект является экземпляром класса javax.servlet.jsp.JspWriter. Например, большая часть статического шаблона на JSP странице, в идеале, должна быть записана в виде соответствующего набора команд out.println(). Область видимости объекта - page.
config - Объект, связанный с конфигурацией сервлета. Является экземпляром класса javax.servlet.ServletConfig. Для JSP страницы область видимости объекта config - page.
page - Объект, связанный с обработкой данной страницы. Область видимости - page

Элементы action

Независимо от того, какой тип будет иметь документ, генерируемый в ответ на запрос пользователя, в общем случае, JSP страница содержит текст и тэги. Очевидно, что последние соответствуют типу генерируемого документа: HTML, XML и т.д. Кроме того, в теле JSP страницы могут содержаться фрагменты программного кода на языке Java, которые должны войти в состав сервлета, получаемого после трансляции: декларации, скриплеты и выражения. Идея заключается в том, чтобы дополнить набор тэгов стандартной разметки специальными тэгами - элементами action, за которыми разработчик бизнес-приложения может скрыть часть программного кода, относящегося к приложению, либо некоторые дополнительные инструкции.

Заметим, что с точки зрения специалиста по верстке документов, элементы action являются такими же тэгами, как и все остальные, а потому допустимо их совместное использование с другими элементами:

В данном примере создается объект класса com.myco. В дальнейшем, чтобы обратиться к нему, достаточно воспользоваться идентификатором “customer”. Например:
<%= customer.getName() %>

По умолчанию, объекты, связанные с элементом JavaBean, по умолчанию имеют область видимости page. Разработчик JSP страницы может указать более продолжительное время существования объекта JavaBean, воспользовавшись при написании элемента jsp:useBean элементом scope. Возможные значения этого атрибута - page, request, session и application - мы обсуждали несколько ранее во время разговора об области видимости объектов, связанных с JSP страницей.

Мы не будем рассматривать остальные атрибуты элемента jsp:useBean. Приведем лишь еще один пример его использования:

Внутреннее устройство элементов JavaBean будет рассмотрено нами в отдельной статье.
jsp:setProperty и jsp:getProperty

Любой класс должен давать доступ к некоторым из своих атрибутов и методов. Отличие элемента JavaBean заключается в том, что доступ к атрибутам у него унифицирован и реализуется на JSP странице с помощью элементов jsp:setProperty и jsp:getProperty.

Элемент jsp:getProperty берет экземпляр Bean, извлекает значение указанного атрибута, преобразует его в случае необходимости в строку и помещает в поток данных, передаваемых клиенту. Например, согласно следующей записи

в генерируемый документ помещается значение свойства name из экземпляра Bean, имеющего идентификатор user.

Элемент jsp:setProperty, в отличие от предыдущего, не извлекает, а задает новое значение атрибута. Например:

Помимо явного задания новых значений, элемент jsp:setProperty позволяет заносить в атрибут объекта значение, извлеченное из запроса клиента. Например:

Данная запись означает, что среди данных, полученных от клиента, находится параметр login и его значение передается для помещения в атрибут name объекта Bean, имеющего идентификатор “user”.

Наконец, когда названия полей в запросе клиента совпадают с названиями атрибутов объекта Bean, предусмотрен еще один вариант, когда разом осуществляется перенос всех значений. Например:

jsp:include

Подобно директиве include, данный элемент позволяет помещать в тело динамически генерируемой страницы статический и динамический материал из внешнего источника. При этом, хотя заимствованный таким образом материал обрабатывается в том же контексте, что и текущая страница, ему предоставляется доступ только к выходному потоку сервлета. Например, код, включаемый в JSP страницу, не должен обращаться к cookies или использовать собственные заголовки, декларирующие кодировку или тип документа.

Отличие директивы include от элемента jsp:include заключается в том, что для нее включаемый материал не может быть динамическим, а поиск и обработка возможных динамических фрагментов осуществляется не отдельно, а после включения, со всей страницей.

Пример использования элемента jsp:include:

jsp:forward

Данный элемент позволяет переадресовать дальнейшее формирование динамической страницы на другую JSP страницу, сервлет или использовать для завершения заранее приготовленный текст. Например:

В следующем, более сложном примере динамическая страница завершается содержимым текстового файла, название которого берется из переменной someValue:
<% String whereTo = "/templates/" + someValue; %>
Как избежать неожиданных и внезапных закрытий Java-приложений, с их корректным сохранением?

  • Создание подключений к базе данных в ADO.NET
  • Основы технологии Server Side Includes или SSI.
  • SSI: вкусно и полезно
  • Как обойтись без использования SSI
  • Включение механизма Server-Side Includes
  • Базовые директивы директивы SSI
  • SSI - что, когда, как?
  • Введение в сервлеты
  • Java Server Pages
  • Тщательная перетасовка колоды карт
  • Многозадачность в JavaMe при HTTP соединении
  • Полезные советы по оптимизации ASP-приложений
  • Раздельная обработка одиночного и двойного клика мыши в swing
  • Создание приложения, работающего с XML-данными
  • GUI в Java c помощью JFace: Создание окна приложения
  • Создание приложения, работающего с XML-данными - 2
  • Часто задаваемые вопросы (FAQ) об ASP
  • Чтение текстовых баз данных из ASP
  • Переменные среды CGI