Сервлеты
В
главе 19
была упомянута технология CGI. Ее суть в том, что сетевой клиент, обычно браузер, посылает Web-серверу информацию вместе с указанием программы, которая будет обрабатывать эту информацию. Web-сервер, получив информацию, запускает программу, передает информацию на ее стандартный ввод и ждет окончания обработки. Результаты обработки программа отправляет на свой стандартный вывод, Web-сервер забирает их оттуда и отправляет клиенту. Написать программу можно на любом языке, лишь бы Web-сервер мог взаимодействовать с ней.
В технологии Java такие программы оформляются как
сервлеты
(servlets). Это название не случайно похоже на название "апплеты". Сервлет на Web-сервере играет такую же роль, что и апплет в браузере, расширяя его возможности.
Чтобы Web-сервер мог выполнять сервлеты, в его состав должна входить JVM и средства связи с сервлетами. Обычно все это поставляется в виде отдельного модуля, встраиваемого в Web-сервер. Существует много таких модулей: Resin, Tomcat, JRun, JServ. Они называются на жаргоне
сервлетными движками
(servlet engine).
Основные интерфейсы и классы, описывающие сервлеты, собраны в пакет javax.servlet. Расширения этих интерфейсов и классов, использующие конкретные особенности протокола HTTP, собраны в пакет javax.servlet.http. Еще два пакета— javax.servlet.jsp и javax.servlet.jsp.tagext — предназначены для связи сервлетов со скриптовым языком JSP (JavaServer Pages). Все эти пакеты входят в состав J2SDK Enterprise Edition. Они могут поставляться и отдельно как набор JSDK (Java Servlet Development Kit). Сервлет-ный движок должен реализовать эти интерфейсы.
Основу пакета javax.servlet составляет интерфейс servlet, частично реализованный в абстрактном классе GenericServiet и его абстрактном подклассе HttpServiet. Основу этого интерфейса составляют три метода:
init (Servietconfig config)
— задает начальные значения сервлету, играет ту же роль, что и метод init () в апплетах;
service(ServletRequest req, ServletResponse resp)
— выполняет обработку поступившей сервлету информации req и формирует ответ resp;
destroy ()
— завершает работу сервлета.
Опытный читатель уже понял, что вся работа сервлета сосредоточена в методе service о. Действительно, это единственный метод, не реализованный в классе GenericServiet. Достаточно расширить свой класс от класса . GenericServiet и реализовать в нем метод service (), чтобы получить собственный сервлет. Сервлетный движок, встроенный в Web-сервер, реализует интерфейсы ServletRequest и ServletResponse. Он Создает объекты req и resp, заносит всю поступившую информацию в объект req и передает этот объект сервлету вместе с пустым объектом resp. Сервлет принимает эти объекты как аргументы req и resp метода service о, обрабатывает информацию, заключенную в req, и оформляет ответ, заполняя объект resp. Движок забирает этот ответ и через Web-сервер отправляет его клиенту.
Основная информация, заключенная в объекте req, может быть получена методами read() и readLine() ИЗ байтового потока класса ServletlnputStream, непосредственно расширяющего класс inputstream, или из символьного потока класса BufferedReader. Эти потоки открываются, соответственно, методом req.getlnputStream() или методом req.getReader (). Дополнительные характеристики запроса можно получить многочисленными методами getxxxo объекта req. Кроме того, класс GenericServlet реализует массу методов getxxxo, позволяющих получить дополнительную информацию о конфигурации клиента.
Интерфейс servietResponse описывает симметричные методы для формирования ответа. Метод getoutputstreamo открывает байтовый поток класса ServletOutputStream, непосредственно расширяющего класс OutputStream. МеТОД getWriter () открывает символьный поток класса PrintWriter.
Итак, реализуя метод service!), надо получить информацию из входного потока объекта req, обработать ее и результат записать в выходной поток объекта resp.
Очень часто в объекте req содержится запрос к базе данных. В таком случае метод service о обращается через JDBC к базе данных и формирует ответ resp из полученного объекта ResultSet.