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

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

.pdf
Скачиваний:
0
Добавлен:
06.09.2026
Размер:
2 Мб
Скачать
Часть 3 Серверные Java-компоненты Servlet 161
Get(). О том, что вывод информации будет сформирован в виде HTML­страницы, говорит пятая строка. Последующие строки, вплоть до один­надцатой, определяют внешний вид выводимых данных. Блок строк с двенадцатой по девятнадцатую предназначен для вывода информации о передаваемых клиентских параметрах. Также в двадцатой строке ука­зывается создание еще одного блока выводимой информации, но теперь это уже информация о заголовках, используемых клиентом. Все то же самое повторяется и для cookies, строки с двадцать седьмой по трид­цать вторую. Поскольку все HTML теги должны быть закрыты, то в тридцать третьей строке указывается операция закрытия HTML тегов. И наконец тридцать четвертая строка предназначена для освобождения ресурсов.
Обработка клиентского запроса — основная задача любого servlet, другой задачей servlet можно с уверенностью назвать формирование ответа для клиента. Выделение необходимой информации из поступив­шего запроса для каждого метода передачи — традиционная задача, выполняемая CGI-скриптами. А там где CGI-скрипты, там и servlet. Для выделения информации â CGI используется переменная QUERY_STRING для метода передачи GET.
Если же информация была отправлена при помощи метода POST, то используется системный поток. Во-вторых, необходимо отделить пере­даваемые параметры от системных символов. Обычно параметры пред­ставляют из себя пары значений, разделенных знаком амперсанта. За­тем выделяются названия (имена) параметров, левые перед знаком рав­но, и их значения правый элемент после знака равно. В-третьих, производится расшифровка URL. Буквенные параметры пересылаются неизменными, а числовые необходимо привести к соответствующему виду, пробелы заменяются знаком плюс, остальные принимают вид %XX, где XX эквивалент знака в ASCII раскладке. Чтобы было более понятно, о чем идет речь, можно привести маленький пример. Переда­ваемые данные состоят из трех слов, являющихся параметрами запро­са, осуществленного в html элементе textfield: param1, ~otherparam и someparam. Следуя выше указанному сценарию, полученная строка бу­дет выглядеть следующим образом: ““%param1%2C+%7Eotherparam %2C+someparam”. Знаки %2C определяют запятую плюс это пробел, %7E — знак тильды. Пересылаемые пары значений param1=val1 &pa­ram2=¶m3=val3 и параметры могут иметь больше чем одно значе­ние param1=val1¶m2=val2¶m1=val3. Одним из замечательных свойств servlet является использование языка Java. Другим замечате­льным свойством можно считать автоматическую синтаксическую про­верку поступившего на servlet запроса. Работа с пересылаемыми пара­метрами обязывает создателя servlet знать о наличии HTML-форм на странице и параметрах, передаваемых этими формами.
Методы по работе с HTTP-протоколом, doGet() и doPost(), имеют два параметра: HttpServletRequest и HttpServletResponse. Эти два объекта представляют полную информацию о request и позволяют контролиро­вать выходящий поток, отправляемый клиенту. Наиболее часто исполь­зование основных методов servlet, особенно предназначенных для обра­ботки HTTP-запросов, связано с получением информации различными
162 Часть 3 Серверные Java-компоненты Servlet
методами самого протокола передачи данных. Возможное решение со­стоит в написании универсального метода обработки клиентского запро­са и затем вызовов данного метода из основных методов servlet.
25.2. Основные объекты request и response
Request — сообщение, посылаемое клиентской программой, подобной Web-браузеру, на сервер. Обычно в самом начале сообщения, в первых строках, указывается протокол и метод передачи данных. Именно с этими данными можно манипулировать для получения более подробной информации о клиенте, обратившемся с запросом.
Обычный объект request порожден от стандартного интерфейса Ser­vletRequest.
Данный объект ассоциирован с клиентским запросом. Обычно явля­ется одним из аргументов основного метода service().
Объект ServletRequest наследует методы родительского интерфейса по работе с клиентскими значениями и атрибутами входящего потока. Для работы с протоколом, зависимым servlet, в методах doGet() и do­Post() используется объект класса HttpServletRequest, интерфейса ServletRequest
.
порожденного от
Версия 2.1 API servlet использует два механизма обработки объекта request. Первый использует специальные методы присваивания атрибу­тов объекту request, другой использует специальные ресурсы.
Методы getAttribute(), getAttributeNames() и setAttribute() исполь­зуются только для объекта request, порожденного от класса HttpServ­letRequest, работающего с HTTP-протоколом. Если необходимо исполь­зовать эти методы с другим протоколом передачи, то объект request должен наследоваться от класса ServletRequest. Методы предназначе­ны, прежде всего, для использования с объектом класса RequestDispatc­her. Именно класс RequestDispatcher чаще всего используется для пе­ренаправления запроса в другой ресурс или получения клиентского за­проса из другого ресурса. Использование атрибутов гарантирует правильную обработку объектом RequestDispatcher клиентских запро­сов. Метод getRequestDispatcher(), в отличие от своего брата близнеца ServletContext.getRequestDispatcher(), не может работать с относитель­ными путями.
Следующий ряд методов предназначен для получения ресурсов из внешних источников для объекта request. Методы getResource() и get­ResourceAsStream() объекта ServletContext обеспечивают доступ к внешним ресурсам, таким, как конфигурационный файл или база дан­ных.
Методы getCharacterEncoding(), getContentLength(), getContentTy­pe() предназначены для получения сведений о приложении, его объеме MIME типе и используемой кодировке:
out.println("getCharacterEncoding: " + request.getCharacterEncoding());
out.println("getContentLength: " + request.getContentLength());
out.println("getContentType: " + request.getContentType());
out.println("getProtocol: " + request.getProtocol());
Часть 3 Серверные Java-компоненты Servlet 163
out.println("getRemoteAddr: " + request.getRemoteAddr());
out.println("getRemoteHost: " + request.getRemoteHost());
out.println("getScheme: " + request.getScheme());
out.println("getServerName: " + request.getServerName());
out.println("getServerPort: " + request.getServerPort());
out.println("getAuthType: " + request.getAuthType());
out.println("getMethod: " + request.getMethod());
out.println("getPathInfo: " + request.getPathInfo());
out.println("getPathTranslated: " + request.getPathTranslated());
out.println("getQueryString: " + request.getQueryString());
out.println("getRemoteUser: " + request.getRemoteUser());
out.println("getRequestURI: " + request.getRequestURI());
out.println("getServletPath: " + request.getServletPath());
out.println();
Входящий поток бинарных данных можно получить, используя ме­тод getInputStream(). В отличие от потока получение текстовых данных осуществляется методом getReader().
Для работы с передаваемыми параметрами служат методы getPara­meter(), getParameterNames(), getParameterValues(). Служебную ин­формацию об удаленном пользователе получают, используя специаль­ные методы getProtocol(), getScheme(), getServerName(), getServer­Port(), getRemoteAddr(), getRemoteHost(), getRealPath(), à также используемых в локалях (географически зависимых данных) getLoca­le(), getLocales(). И наконец, если приложение использует протокол HTTPS, то это можно определить с помощью метода isSecure(), возвра­щающего значение true, в случае использования такового протокола.
Объект request имеет ряд методов для работы с CGI переменными, а также по выделению информации из поступившего клиентского запроса.
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.println("<TR><TD>" + paramName + "\n<TD>");
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.print("<I>No Value</I>");
else
out.print(paramValue);
} else {
out.println("<UL>");
for(int i=0; i<paramValues.length; i++) {
out.println("<LI>" + paramValues[i]); }
out.println("</UL>"); } }
Объект response представляет набор информации, отправляемой сервером клиенту. Данный объект порожден от интерфейса ServletRes­ponse.
164 Часть 3 Серверные Java-компоненты Servlet
Методы объекта response можно разделить на несколько частей, предназначенных для выполнения различных задач по работе создания клиентского ответа. Непосредственно за получение выходящего потока отвечает метод getOutputStream (), другой метод используется при со­здании текстового ответа getWriter(). Установкой типа передаваемого приложения и за его длину отвечают методы setContentLength(), getC­haracterEncoding(), setContentType().
Несколько методов предназначено для работы с системным буфером.
Метод setBufferSize() указывает размер объекта response. Малень­кий размер буфера позволяет очень быстро пересылать данные клиен­ту. Метод должен вызываться перед оправкой ответа. Получение раз­мера буфера getBufferSize() и сброс буфера flushBuffer(), а также его очистку reset() осуществляют указанные методы.
Об успешном выполнении ответа можно узнать, используя метод is­Committed().
Для работы с национальными настройками есть пара методов setLoca­le() установки и getLocale() получения значений национальных настроек.
Так же как и объект request, является вторым обязательным аргу­ментом основного метода service(). Объект используется для передачи клиенту данных различных типов. При отправке бинарных данных ис­пользуется выходящий поток ServletOutputStream, помощи метода getOutputStream()
. Если же отправляются текстовые
получаемый при
данные, то используется стандартный поток PrintWriter, доступ к кото­рому можно получить, используя метод getWriter()
. Если же посылают­ся смешанные данные, и текстовые и бинарные, то для передачи легче воспользоваться объектом класса ServletOutputStream .
Метод setContent() объекта response предназначен для установления типа отправляемых данных и должен использоваться до того, как дан­ные будут переданы клиенту при помощи выходного потока PrintWrti­ter или ServletOutputStream. Для изменения стандартных кодировок используется метод setLocale(java.util.Locale)
. Обычно в Web-страницах используется кодировка ISO-8859-1, для ее изменения и используется вышеуказанный метод. Как и метод setContentType(), метод setLocale() используется только до формирования выходящего потока.
Для работы с HTTP-протоколом существует другая версия объекта response, порожденная от интерфейса HttpServletResponse, который, в свою очередь, расширен от интерфейса ServletResponse.
Response — объект, общающийся с клиентом по HTTP-протоколу, имеет дополните­льные методы для работы со специфическими http-данными, cookies, headers, status code.
Минимальная структура servlet, обрабатывающего GET метод пере­дачи HTTP-протокола рассмотрена ниже. При использовании другого метода передачи, например POST, необходимо в пятой строке примера заменить метод doGet() на соответствующий doPost().
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SomeServlet extends HttpServlet {
Часть 3 Серверные Java-компоненты Servlet 165
public void doGet (HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
PrintWriter out = response.getWriter();}
out.println("Hello World"); }
Данная структура представляет "скелет" обычного servlet, обрабаты­вающего HTTP-запросы, т. е. метод service() заменен методом doGet(). Строки первая, вторая, третья указывают импортирование пакеты, не­обходимые для создания servlet. Первый оператор импортирования ja­va.import.io.* обязателен, если предполагается в дальнейшем использо­вать объекты типа PrintWriter, находящийся в пакете java.io. Хотя в пакете javax.servlet имеются собственные классы по организации рабо­ты с входящими и выходящими потоками ServletOutputStream и Serv­letInputStream, очень часто используется объект класса PrintWriter для работы с текстовыми данными. Четвертая строка содержит определе­ние создаваемого класса SomeServlet порожденного от HttpServlet. Не запрещается использование любой другой конструкции для создания объекта, принятого в Java-приложениях. Например, вместо короткого имени родительского класса HttpServlet из пакета javax.servlet, вторая строчка с оператором import, можно указать его полное имя javax.serv­let.HttpServlet, тогда оператор import в третьей строке не потребуется, при условии, что не будут импортироваться другие классы из данного пакета. Пятая строка определяет основной метод doGet(), которому пе­редаются два параметра: request класса HttpSevletRequest, находяще­гося в пакете javax.servlet.http, и response класса HttpServletResponse. Именно для этого потребовалось импортировать в третьей строке пакет javax.servlet.http, указанные оператором throws исключительные ситуа­ции ServletException и Ioexception, которые должны быть обязательно обработаны. Шестая строка создает объект out класса PrintWriter из родового пакета java.io, самая первая строка, для вывода данных.
Практически данный servlet ничего не делает, это готовая форма для дальнейшего расширения. Здесь не используются методы init() и dest­roy(), и оператор out не посылает никаких данных обратно клиенту. По­следовательность операторов import не важна, но последовательность используемых объектов методов иногда приходится определять зара­нее. Переменная создается до того, как ее можно будет использовать. Действия этого принципа уже описывались при использовании методов setContentType() и setLocale(), они обязательно используются перед пе­редачей данных.
Для придания servlet какой-нибудь функциональности можно заста­вить объект out выводить какую-нибудь информацию, дополняя пример седьмой строкой приблизительно так: out.println("Hello World"); }
Теперь servlet должен будет вывести сообщение Hello World в окне браузера клиента. Но пока это только текстовый.java файл, который не­обходимо откомпилировать стандартным javac компилятором, входя­щим в Java Development Kit, или другим Java-компилятором. После успешной компиляции полученный.class необходимо разместить на сер­вере, в специальной директории или папке, называемой servlet.
166 Часть 3 Серверные Java-компоненты Servlet
И наконец, чтобы увидеть великое диво — работающий servlet, нужно обратиться ê «шедевру» èç обычной HTML-страницы http://host/servlet/SomeServlet.
Не прекращая ни на минуту совершенствовать творение, заставим его вывести строку в более элегантном виде, сделав небольшие дополне­ния в первом варианте. Во-первых, добавим вызов объекта response и, используя его метод setContentType() с параметром ("text/html"), ука­зывающим, что выводимая строка будет HTML-текстом. Все это указано в строке восемь нижеследующего примера. А оператор out примет более внушительный вид, теперь в нем прописаны еще и HTML теги:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class NewSameSevlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
ServletOutputStream out = response.getOutputStream();
response.setContentType("text/html");
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML
4.0 " + "Transitional//EN\">\n" + "<HTML>\n" + "<HEAD><TITLE>Hello World</TITLE></HEAD>\n" +
"<BODY>\n" + "<H1>Hello WWW</H1>\n" + "</BODY>
</HTML>");}
public void doPost (HttpServletRequest request, HttpServletRespon­se response){doGet (request,response)}}
Только что созданный servlet будет обрабатывать HTTP-запросы, о чем говорит четвертая строка, поскольку servlet расширен от HttpServ­let. В пятой строке описывается метод doGet(), содержащий основное тело программы. Шестая строка содержит стандартные классы исклю­чительных ситуаций. В седьмой строке создается объект out класса ja­vax.servlet.ServletOutpurStream для формирования ответа в виде тек­ста. Объекту out присваивается значение выходящего потока. После указывается, что текст ответа является HTML-текстом при помощи ме­тода setContentType(). В девятой строке указывается HTML-конструк­ция DOCTYPE, обычно она игнорируется Web-браузерами и предназна­чена для указания версии используемого HTML.
Если неизвестно, каким способом будет осуществляться доступ к ser­vlet, можно в одном из основных методов описать тело и затем вызвать этот основной метод из различных других методов. В десятой строке именно этот способ указан. Можно создать один универсальный метод, обрабатывающий клиентский запрос, вызов которого осуществляется из остальных методов.
Часто возникает необходимость обновления данных, получаемых клиентом без организации запроса клиента. Поставляемые данные должны обновляться с какой-то периодичностью. Не каждый пользова­тель имеет привычку нажимать кнопку refresh (обновление данных) че­рез определенные интервалы времени.
Часть 3 Серверные Java-компоненты Servlet 167
Чтобы пользователю этого не приходилось делать, в HTML-странице нужно вставить нечто похожее на:
<META HTTP-EQUIV="Refresh" CONTENT="2; URL=http://someWhe-
re.com/servlet/ReloadServlet">
Непосредственно данные эта строка не обновит, но страницу по ука­занному адресу http:// someWhere.com/servlet/ReloadServlet перезаг­рузит каждые две секунды.
В рабочем servlet можно только добавить параметр объекта out:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class NewSameSevlet extends HttpServlet implements Seriali-
zable{ public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/html");
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML
4.0"+ "Transitional//EN\">\n" + "<HTML>\n" +
"<HEAD><TITLE>Hello World</TITLE></HEAD>\n" +
"<BODY>\n" + "<H1>Hello WWW</H1>\n" + "</BODY> </HTML>");
out.write ("<META HTTP-EQUIV=\"Refresh\ "CONTENT=\"2; URL=http://SomeWhere.com/servlet/ReloadServlet\"> ");}}
Пример не отличается от вышеприведенного, но содержит в допол­нительной, тринадцатой строке, специальную HTML-конструкцию об­новления страницы.
Другой приятной необходимостью является поиск нужной информа­ции, чаще всего поисковые механизмы реализовываются на Perl, пре­красно приспособленном для работы со строками, но Java ничем не ху­же, просто значительно мощнее.
Так как параметры передаются парами параметр=значение, а между парами служебные знаки, обычно амперсанда (&) для протокола HTTP, то кроме самого поиска приходится еще и разбирать приходящую стоку. Одним из замечательных свойств servlet является встроенная проверка обрабатываемых строк, проводимая методом getParametr()объекта requ­est. Возвращаемые значения типа строк String. Если возвращаемый па­раметр не имеет значения, то возвращается имя параметра и возвраща­ется значение null при отсутствии параметра. Параметр может иметь больше чем одно значение, в этом случае нужно воспользоваться мето­дом getParameterValues() того же объекта. Тогда возвращается коллек­ция (массив) строк. В реальных приложениях может существовать не­сколько параметров, для которых осуществляется поиск. Использование метода getParameterNames () возвращает коллекцию всех параметров.
168 Часть 3 Серверные Java-компоненты Servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class readParams extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/html");
String title = "Reading Three Parameters";
out.println("<BODY>\n" + "<H1 ALIGN=CENTER>" + title +
"</H1>\n" + "\n" + "<LI>param1: " + request.getParameter("param1") + "\n" +
"<LI>param2: " + request.getParameter("param2") + "\n" +
"<LI>param3: " + request.getParameter("param3") + "\n" +
"</UL>\n" + "</BODY></HTML>"); } public void doPost(HttpServletRequest request, HttpServletResponse
response)throws ServletException, IOException {doGet(request, res­ponse); }}
И опять ничего страшного не произошло. Был импортирован еще один пакет, теперь четвертая строка содержит оператор import java.util для работы с коллекциями, десятая строка не несет никакой функцио­нальной нагрузки, просто текстовая строка. Основными здесь являются строки одиннадцатая, двенадцатая и тринадцатая — именно здесь по­лучают параметры. Четырнадцатая строка позволяет использовать ме­тод doPost(), имеющий такие же параметры, как doGet(), и вызываю­щий соответствующий метод. Эта конструкция предпочтительнее в ис­пользовании, ÷åì написание различных файлов ñ различными методами, ибо нет никакой гарантии, каким способом будут переданы данные на сервер GET или POST.
Но прочитать параметры полдела, их надо обработать и отправить ответ, использующий полученные данные.
Отображение данных не менее важная задача. Для чего тогда поль­зователь посылает запрос? Передаваемых параметров может быть не­сколько, обычно для работы с множеством однотипных объектов про­граммисты используют разные виды коллекций. Java поддерживает не­сколько типов коллекций, такие, как хэш-таблицы, массивы, бинарные деревья. Все коллекции находятся в родовом пакете java.util, который необходимо импортировать для работы с коллекциями объектов, обра­батываемых servlet.
Чтобы работать с конкретными параметрами, необходимо воспользо­ваться методом getParameterNames() объекта, порожденного от HttpServletRequest. Другой метод денного объекта getParameterValues() предназначен для получения значений передаваемых параметров:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
Часть 3 Серверные Java-компоненты Servlet 169
import java.util.*;
public class ShowParameters extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/html");
String title = "Reading All Parameters";
out.println("<BODY BGCOLOR=\"#FDF5E6\">\n" +"<H1
ALIGN=CENTER>" + title + "</H1>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Parameter Name
<TH>Parameter Value(s)");
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.println("<TR><TD>" + paramName + "<TD>");
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length == 0)
out.print("<I>No Value</I>"); else out.print(paramValue); } else {out.println("<UL>");
byte _l=paramValues.length;
for(byte i=0; i<_l; i++) { out.println("" + paramValues[i]); }
out.println("</UL>"); } }
out.println("</TABLE>\n</BODY></HTML>"); }
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response); }}
Первые одиннадцать строк уже не представляют практического ин­тереса, важнее то, что будет происходить с двенадцатой строки. Здесь указывается коллекция объектов paramNames, в которую помещаются имена всех параметров переданных клиентов. Поскольку объектов все­таки несколько, то одним из решений является помещение всех имен параметров в коллекцию, чтобы легко просмотреть все элементы в дан­ной коллекции. Объект paramNames наследует интерфейс Enumeration. В тринадцатой строке проверяются все объекты в этой коллекции с по­мощью оператора while и метода hasMoreElements(), возвращающего значение true, если достигнут последний элемент коллекции. И пока не достигнут последний объект в коллекции, каждый следующий элемент получает имя и преобразуется в строку, так как параметры могут быть не только типа String, четырнадцатая строка, String paramName = (String)paramNames.nextElement(). В пятнадцатой строке оператором out выводятся все параметры, чаще всего такая операция не является обязательной, а служит для проверки. Пока еще конечный элемент не
170 Часть 3 Серверные Java-компоненты Servlet
определен, создается массив строк, именно здесь у каждого параметра читается его значение, шестнадцатая строка. Необходимо отметить, что начальным элементом в массиве является нулевой, а не первый. Строки с семнадцатой по девятнадцатую проводят проверку наличия в массиве значение каждого параметра. Если имеется одно значение, то выводит­ся значение нулевого элемента, если же значения отсутствуют, то вы­водится сообщение No Value, в противном случае отображаются все присутствующие в массиве значения. В двадцать третьей строке описы­вается еще один основной метод — doPost(), предназначенный для об­работки запроса, посланного методом POST HTTP-протокола. В методе отсутствует дублирование операторов метода doGet(), а просто вызыва­ется сам метод doGet().
В общем виде запрос выглядит как HTML-страница, если клиентом является Web- браузер, по-другому это будет выглядеть для WAP- и Java-клиентов. Пока рассмотрению подлежит только клиент, использу­ющий Web браузер, как самый распространенный.
25.3. Классы исключительных ошибок servlet
В стандартном servlet API описано два класса исключительных ситу­аций.
Первый — javax.servlet.ServletException. зуется для обработки ошибок, возникших в момент исполнения servlet.
Второй класс javax.servlet.UnavailableException ступность servlet в момент поступления клиентского запроса на сервер.
Объект этого класса исполь-
— указывает на недо-
25.4. Область видимости объектов
Для большинства используемых servlet существуют три основных области видимости, в отличие от других серверных Java-компонентов. В обычных Web-приложениях серверные компоненты выполняют раз­личные задачи. И для каждой задачи создается свой servlet. Можно ко­нечно же использовать один-единственный servlet для выполнения всех задач, но это практически невозможно, да, наверное, и не нужно. Но суть в том, что различные серверные компоненты должны взаимодейст­вовать между собой, передавая друг другу различные параметры и реа­гируя на поведение остальных серверных компонентов. Именно взаимо­действие и определяет область видимости.
Доступ одного ресурса к другому осуществляется за счет формиро­вания запроса. Таким ярко выраженным примером для servlet можно назвать метод forward() объекта RequestDispatcher. Объект доступен только для конкретного данного запроса.
Объекты, используемые в клиентской сессии, доступны и другим объек­там, доступ к которым имел клиент. В данном контексте хранилищем вре­менной клиентской информации выступает объект класса HTTPSession.
Работа приложения тесно связана с объектами, хранящимися, в общей «куче», доступ к которой обеспечивает объект класса ServletContext. Испо­льзуя его методы, можно получить доступ ко всем объектам приложения.