logo search
Проектирование инт-прил / лекции / Проектирование инет приложений

Сервлеты

В языке Javaсуществует специальный класс -HttpServlet- предназначенный для реализации обмена с клиентом по протоколуHTTPи допускающий расширение этого протокола. Таким образом, на основе сервлета можно строить - какWeb-приложения, так иWeb-сервисы. Сервлет запускается в специальном контейнере, который обеспечивает жизненный цикл сервлета. Контейнер сервлетов - это специальное серверное приложение, которое может быть запущено как самостоятельныйWeb-сервер, либо как поставщик контента для другогоWeb-сервера, либо входить в состав сервера приложений на языкеJava. В качестве контейнера сервлетов может выступать, например,ApacheTomcatсервер. По сути, сервлет является "антиподом" апплета: апплет выполняется на клиентской части, сервлет - на серверной.

Точно так же, как и applet, сервлет имеет жизненный цикл. При поступлении запроса от клиента контейнер сервлетов определяет, загружен ли уже данный сервлет. И если не загружен - сервлет загружается в память контейнера и вызывается методinit(). В случае, когда контейнеру необходимо удалить сервлет, будет вызван методdestroy(). Оба этих метода вызываются только один раз за время жизни сервлета и могут быть перекрыты разработчиком для реализации собственных функций инициализации и уничтожения сервлета. Точно так же, как и в случае с апплетом, эти методы не являются заменителем конструктора и деструктора класса. Каждый запрос клиента обрабатывается в отдельном потоке, для чего контейнер вызывает функциюservice()после поступления каждого запроса. Можно переопределить метод

void processRequest(HttpServletRequest request, HttpServletResponse response){}

который отрабатывается на каждый поступающий от клиента запрос. Но чаще переопределяют один или оба метода

void doGet(HttpServletRequest request, HttpServletResponse response){} void doPost(HttpServletRequest request, HttpServletResponse response){}

Первый из них срабатывает после получение от клиента GET-запроса, второй - POST-запроса. Класс сервлета имеет и другие предопределенные методы, позволяющие сформировать реакцию на различные запросы: doDelete, doPut, doHead и т.д. Метод service() первым принимает запрос и осуществляет его перенаправление соответствующему doXXX(). Можно использовать метод service() для реализации каких-то общих для запроса операций, например, для записи статистики по приходящим клиентам в базу данных.

Как правило, предопределенные функции имеют два параметра: request и response. Объект request полностью содержит в себе информацию о поступившем запросе. Значениями параметров запроса могут быть только строки (String), которые можно привести к какому-нибудь другому типу (int, float и так далее). Для работы с параметрами класс клиентского запроса предоставляет несколько функций:

String getParameter( String name ) - получить параметр с именем name.

Enumeration getParameterNames() - возвращает имена всех присутствующих в запросе параметров

Как уже упоминалось ранее, протокол HTTP не содержит информацию о сеансе работы с клиентом. Класс сервлет для реализации сессионности предоставляет как cookies (на стороне клиента), так и доступ к объекту HttpSession (на стороне сервера):

Cookie[] getCookies() - возвращает массив объектов Cookie, сохраненных на клиенте

HttpSession getSession(boolean create) - возвращает объект HttpSession, ассоциированный с текущим сеансом клиента. Если параметр create установлен в true - сервлет создаст новый объект HttpSession в случае, если для клиента его еще не существовало.

Параметр вызова процедур doXXX() response содержит объект ответа, который будет передан клиенту. Есть возможность установить передаваемый тип данных (заголовок Content-Type в HTTP Response):

response.setContentType("text/html");

Класс response имеет два варианта получения потока передачи данных клиенту. Если передается текстовое сообщение, то используется метод

PrinterWriter getWriter();

а в случае необходимости передачи клиенту бинарной информации, например при передаче изображений, используется метод

ServletOutputStream getOutputStream();

Существуют и другие функции для работы с объектом response. Например, можно принудительно переадресовать клиента на другое Web-приложение, используя метод response.sendRedirect( String new_url );

      1. JSP

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

Дальнейшее развитие технологии сервлетов привело к созданию JSP,JavaServerPages, по сути своей напоминающей работу рассмотренного ранее препроцессораPHP: берется исходный код серверной страницы, транслируется в байт-код сервлета при помощи специального компилятораJasperи затем выполняется внутри контейнера. Такой подход позволяет прямо внутриHTML-страниц вызывать функцииJavaили вообще включать кодJavaнапрямую в страницу.

ВыраженияJSPзаключаются в тэги<%=и%>. КонтейнерJSPпреобразует результат работы каждого выражения - в строку, которая выводится как часть ответа клиенту. Выражения вычисляются на момент запроса страницы клиентом. Пример использования выражений вJSP:

<%= new java.util.Date() %>

Использование на странице такого выражения приведет к формированию (в строковом виде) текущей даты-времени.

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

<%! int counter = 0; %>

Скриптлеты(сценарии) включаются в тэги<%и %>. Скриптлеты содержат фрагменты кода, написанные на языкеJava. При работе внутри скриптлетов доступен ряд переменных выполняющейся страницы. Например, существуют упоминавшиеся ранее объектыrequestиresponse. Текст сценариев и текстHTMLмогут чередоваться между собой, при этом выполнение сценария (скриптлета) будет продолжаться при следующем появлении куска кода:

<html>

<body>

<% // Начало скриптлета

String name = request.getParameter("firstName");

if ( name != null ) {

%> <%-- Закрытие скриптлета. Далее идет кусок HTML кода,

который появится на странице, если в запросе был

указан параметр firstName --%>

<h1>Hello, <%= name %>!</h1>

<% // продолжение сценария.

} // закрытие блока if (name)

else { // что делаем, если параметра firstName

// в запросе не было.

%> <%-- Снова скриптлет закончился, переходим на HTML.

Если клиент не предоставил нам свое имя - просим

его это сделать при помощи формы ввода %-->

<!-- Форма для ввода имени клиента -->

<form name="inputForm" action="welcome.jsp" method="get">

<p>Введите свое имя и нажмите Submit</p>

<input type="text" name="firstName" />

<input type="submit" value="Submit" />

</form>

<% // Снова переходим на скриптлет - нужно закрыть

// блок else.

};

%>

</body></html>

Комментариивключаются в тэги<%--и--%>и могут быть использованы в любой частиJSPстраницы, но не внутри скриптлетов. Внутри скриптлетов действуют правила для комментариев, определенные языкомJava. То есть комментарии могут быть однострочными, начинающимися с символов //, и многострочными, ограниченными символами /* и */. В отличие отHTML- комментариев ( <!-- --> ), комментарииJSPне передаются клиенту. Приведенный выше пример демонстрирует работу разных комментариев в странице.

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

<%@ page import = "java.util.*" %>

<%@ include file="welcome.html" %>

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

<jsp:include>- динамически подключает другой ресурс к данной странице

<jsp:forward>- переадресовывает обработку запроса на другой ресурс (страницу).

<jsp:plugin>- дает возможность добавления в страницу подключаемого компонента в виде специфического для браузераHTML-элемента <object> или <embed>. В частности, при помощи действия<jsp:plugin>можно добавить на страницуJavaApplet.

Технология jspраспространена достаточно широко. Одна из причин этого - наличие модулей вWeb-серверах, которые позволяют использовать один программный продукт (Web-сервер) в качестве полного окружения: он является и контейнером сервлетов, содержит в себе средства компиляцииJSPи собственно реализует работу с клиентом по схеме "запрос-ответ". Кроме того, на сегодняшний день существуют фреймворки, позволяющие объединить в одно целое технологии сервлетов,JSPи парадигмуMVC. Примером такого фреймворка может служитьJakartaStruts.