![]() |
|
||
|
|
|
Гномы серверов. Часть 2(Дмитрий Рамодин) В первой части этой статьи мы познакомились с возможностями сервлетов. Теперь рассмотрим, как настроить и запустить сервлет, после чего разберем конкретный пример сервлета. Запуск и настройка сервлетовНастало время остановиться на деталях настройки и запуска сервлетов. Для этого следует поговорить о файле свойств. Имя этого файла — servlet.properties. В нем в виде пар «ключ—значение» хранятся свойства, используемые для конфигурации, создания и инициализации сервлетов. Изначально для любого из сервлетов предопределено два свойства. Первое, servlet.<имя сервлета>.code, определяет имя сервлета и ставит его в соответствие двоичному class-файлу сервлета. Например, если вы скомпилировали класс сервлета с именем MyServletClassName, то получите в результате компиляции файл с именем MyServletClassName. class и можете присвоить ему краткое имя, скажем, myservlet, следующим образом:
servlet.myservlet.code=
MyServletClassName
Теперь, когда вы обратитесь к сервлету с именем myservlet, сервер найдет эту строку в файле свойств и, опираясь на найденное значение, загрузит класс MyServletClassName, инициализирует его и передаст ему ваш запрос. Следует помнить о том, что имя class-файла должно задаваться полностью, включая имя пакета, в котором определен класс. Второе свойство, servlet.<имя сервлета>.initargs, определяет передаваемые сервлету параметры инициализации. Значения такого рода параметров могут быть получены сервлетом методом getInitParameter. Если параметров несколько, они отделяются друг от друга запятыми. Пример задания параметров: servlet.myservlet.initargs= \ someParameterName1=someValue, someParameterName2=otherValue Файл servlet.properties помещают в определенный каталог на сервере, где хранятся class-файлы. Заметим, однако, что разные серверы допускают альтернативное местоположение файла свойств (по настройке администратора). Теперь поговорим об утилите servletrunner, которая по сути является простейшим Web-сервером, специально предназначенным для работы с сервлетами. После запуска он «слушает» порт 8080, и если произошел запрос, то, обратившись к сервлету, servletrunner получает от него ответ и пересылает последний программе-клиенту. Командная строка servletrunner имеет различные опции, но полезными могут оказаться лишь следующие:
Никаких дополнительных настроек вам не потребуется. Просто запустите утилиту servletrunner и обращайтесь к ней с помощью браузера или другой клиентской программы. Главное, чтобы servletrunner могла найти ваши сервлеты. Теперь вкратце о том, как обратиться к сервлету из Web-браузера. По умолчанию адрес URL для отправки запроса состоит из нескольких частей: имени компьютера, номера порта, каталога servlet, имени сервлета и списка параметров. К примеру, обратиться к сервлету myservlet, находящемуся на локальном компьютере, можно так: http://localhost:8080/servlet/myservlet?param=somevalueНапомним, что, тоже по умолчанию, утилита servletrunner (и некоторые серверы Web) «слушает» запросы к порту с номером 8080. Приведенный выше запрос обращается к сервлету myservlet, передавая ему параметр param со значением somevalue. Это весьма полезно, когда нужно задавать параметры запроса «на лету» (в отличие от параметров инициализации). Пример сервлетаЧтобы все рассказанное о сервлетах не осталось для вас пустыми словами, создадим собственный сервлет, который будет выводить в окне браузера список файлов в определенном каталоге компьютера-сервера, а заодно и показывать количество файлов и их местоположение. Готовый исходный текст показан в листинге. Мы не станем детально описывать теги HTML, которые сервлет вставляет в генерируемую страницу, — обратитесь самостоятельно к документации по этому языку. Весь вывод данных будет производиться методом println класса PrintWriter, что является наиболее удобным вариантом посылки текстовых данных. Начнем с того, что опишем класс сервлета, наследующий HttpServlet, и импортируем необходимые классы. После чего займемся методом doGet — главной частью сервлета:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class SampleServlet extends HttpServlet
{
public void doGet( HttpServletRequest req,
HttpServletResponse res)throws
ServletException, IOException
{
После чего методом setContentType серверу сообщается, что возвращаемые данные — страница HTML (MIME-тип «text/html»). Если этого не сделать, то сервер решит, что вы посылаете обычный текст. Метод generateHeader, который идет следом, убирает детали генерации стандартного заголовка Web-страницы, чтобы не загромождать исходный текст. Первый параметр этого метода — заголовок генерируемой страницы, а второй — ссылка на поток вывода, куда этот метод должен пересылать данные. Следующий блок занимается разбором параметров, переданных сервлету:
if((param = req.getParameter(”dirToShow”)) == null)
if((param = getInitParameter(”dirToShow”)) == null)
{
w.println(”<H1><FONT COLOR=RED>” +
”The <EM>dirToShow</EM> parameter
required!</FONT></H1>”);
return;
}
Сначала сервлет пытается считать значение параметра dirToShow из адреса URL (метод getParameter). Если такого параметра в запросе нет, то предпринимается попытка получить параметр с этим же именем из файла свойств (метод getInitParameter). Если и там параметр не обнаружен, запрос прерывается, а в ответ клиенту посылается сообщение (рис. 1). Если же параметр найден, то его значение запоминается для дальнейшего использования. В следующем блоке исходного текста проверяется, является ли заданный параметр именем каталога и существует ли каталог с таким именем. Если нет, то следует генерация сообщения об ошибке:
File root = new File(param);
if(!root.isDirectory())
{
w.println(”<H1><FONT COLOR=RED>” +
”The parameter is not a directory
or not exist!</FONT></H1>”);
return;
}
Когда все формальности соблюдены, у каталога запрашивается список всех имеющихся файлов и по нему вычисляется общее количество их в каталоге. Заодно генерируется строка, показывающая полное имя каталога:
File[] fileList = root.listFiles();
w.println(”<H2><FONT COLOR=TEAL>” +
”Total number of files in the choosen directory - ” +
fileList.length + ”</FONT></H2>”);
w.println(”<H3><FONT COLOR=PURPLE>” +
”Directory path - ” + param +
”</FONT></H3><HR>”);
Имена файлов выводятся методом printName, который приведен чуть ниже. Для форматирования списка применяется таблица, поэтому нужны две дополнительные строки, формирующие с помощью пары тегов <TABLE> и </TABLE> таблицу с невидимой рамкой:
w.println(”<TABLE BORDER=0 CELLSPACING=5>”);
for(int i = 0; i < fileList.length; i++)
printName(fileList[i], w);
w.println(”</TABLE><HR>”);
generateFooter(w);
Завершается вывод генерацией стандартного окончания HTML-страницы с помощью метода generateFooter. Теперь о методе printName. Он чрезвычайно прост и состоит из строчки, которая проверяет, является ли выводимое имя каталогом или простым файлом. После этого в специально отведенную переменную записывается комментарий о типе. Далее в два столбца в таблицу выводятся тип файла (простой файл или каталог) и его имя:
private void printName(File name, PrintWriter output)
{
String type = name.isDirectory()
? ” (Directory)” : ” (File)”;
output.println(”<TR><TD>” + type +
”</TD><TD><FONT COLOR=BLUE>”
+ name.getName() +
”</FONT></TD></TR>”);
}
Остается лишь рассмотреть вспомогательные методы generateHeader, generateFooter getServletInfo. Они настолько просты, что вы без труда разберетесь с ними самостоятельно:
private void generateHeader
(String title, PrintWriter output)
{
output.println(”<HTML>\n<HEAD>\n<TITLE>” +
title + ”</TITLE>\n</HEAD>\n<BODY>”);
}
private void generateFooter(PrintWriter output)
{
output.println(”</BODY>\n</HTML>”);
output.flush();
output.close();
}
public String getServletInfo()
{
return ”This servlet shows a content of a directory” +
”mentioned in dirToShow parameter or property.”;
}
}
Отлаживать подобного рода сервлеты не просто, а очень просто. Нужно только открыть в браузере режим просмотра исходного текста страницы — и все ваши ошибки сразу же становятся видны. Ниже приведен исходный текст файла свойств servlet.properties :# dirlist servlet servlet.dirviewer.code=SampleServlet servlet.dirviewer.initArgs=\ dirToShow=D:\\SUN\\SDK\\examples
Обратите внимание, что символ «обратная косая» в пути к каталогу задается по правилам языка Java, т. е. двойными «обратными косыми». Можно, однако, использовать и одинарную «прямую косую», как это принято в ОС UNIX. На рис. 2 показано, как примерно будет выглядеть результат работы сервлета. В качестве запроса была введена строка: http://mitrich/servlet/dirviewer?dirToShow=D:/Sun/SDK/examplesЗапускается сервлет следующей строкой: servletrunner -p 80 -d E:\PROJECTS\Java\Servlet -r E:\PROJECTS\Java\ServletНе забудьте, что все каталоги актуальны лишь для компьютера, на котором работает автор. Вы же подставите собственные пути. Изготовление сервлетов в Borland JBuilder 2Довольно хорошими возможностями по созданию сервлетов обладает пакет Borland JBuilder 2. Если заглянуть в список имеющихся у него мастеров, то можно обнаружить соответствующую пиктограмму, щелкнув на которой вы запускаете программу генерации исходного текста сервлета (рис. 3).
Сначала потребуется ввести исходные данные для создания нового проекта: название проекта, имя автора и т.д. (рис. 4).
Сам мастер генерации сервлета запускается чуть позже, когда создан проект. Диалоговая панель мастера (рис. 5) предложит создать те элементы сервлета, с которыми вы уже познакомились в предыдущей части статьи. Опция Implement SingleThreadModel добавляет в список наследования класса сервлета интерфейс SingleThreadModel, не разрешающий множественное обращение к сервлету. Generate HTML Page создает Web-страницу для сервлета. И наконец, вы можете включать генерацию нескольких основных методов-обработчиков для сервлета: service, doGet, doPost, doPut, doDelete.
На следующем этапе задаются параметры инициализации. Кроме имени параметра и его типа также задаются: описание параметра; переменная внутри сервлета, которой будет передано значение параметра после его считывания; значение параметра по умолчанию; имя метода сервлета, в котором должно происходить считывание параметра (рис. 6). Если ввести параметры так, как это показано на предыдущих рисунках, то вы получите проект с двумя Java-классами. Первый представляет собой простейший сервер. Он настроен на порт 8080 и умеет распознавать две опции командной строки -p и -d, которыми можно задать порт сервера и каталог с сервлетами соответственно. Вот исходный текст такого сервера, сгенерированный JBuilder:
package Samples;
import sun.servlet.http.*;
public class ServletServer {
public static void main(String[] args) {
boolean portSet = false;
boolean servletDirSet = false;
for (int i = 0; i < args.length; i++) {
if (args[i].equals(”-p”)) {
portSet = true;
}
if (args[i].equals(”-d”)) {
servletDirSet = true;
}
}
int i = 0;
String[] arguments = new String[args.length +
(servletDirSet ? 0 : 2) + (portSet ? 0 : 2)];
for (; i < args.length; i++) {
arguments[i] = args[i];
}
if (!portSet) {
arguments[i++] = ”-p”;
arguments[i++] = ”8080”;
}
if (!servletDirSet) {
arguments[i++] = ”-d”;
String servletDir = System.getProperty(”java.class.path”);
servletDir = servletDir.substring(0,
servletDir.indexOf(java.io.File.pathSeparator));
arguments[i++] = servletDir;
}
HttpServer.main(arguments);
}
}
Сам класс сервлета не делает ничего выдающегося, а просто обрабатывает значение параметра инициализации и элементарным образом реагирует на запросы, выводя некое сообщение:
package Samples;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class TestServlet extends HttpServlet {
public void init(ServletConfig config) t
hrows ServletException {
super.init(config);
//Каталог, содержимое которого нужно показать
try { pathToDir = getInitParameter(”dirToShow”); }
catch (Exception e) { e.printStackTrace(); }
}
String pathToDir = ”E:/Projectes/”;
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(”text/html”);
PrintWriter out = new PrintWriter (response.getOutputStream());
out.println(”<html>”);
out.println(”<head><title>TestServlet<
/title></head>”);
out.println(”<body>”);
out.println(”</body></html>”);
out.close();
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(”text/html”);
PrintWriter out =
new PrintWriter (response.getOutputStream());
out.println(”<html>”);
out.println(”<head><title>TestServlet<
/title></head>”);
out.println(”<body>”);
out.println(”</body></html>”);
out.close();
}
public String getServletInfo() {
return ”Samples.TestServlet Information”;
}
}
* * * Итак, вы получили представление о том, как пишутся сервлеты. К сожалению, без Java Web Server компании Sun трудно отладить сколь-нибудь сложные сервлетные классы, а утилита servletrunner обладает лишь простейшими возможностями по их запуску. Однако компания JavaSoft обещает исправить этот недостаток, включив в следующую версию Java Servlet Development Kit усовершенствованный маленький Web-сервер, с которым процесс отладки и проверки станет намного проще. Листинг: Пример сервлета
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class SampleServlet extends HttpServlet
{
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
String param;
PrintWriter w = res.getWriter();
res.setContentType(”text/html”);
generateHeader(”Directory Viewer Servlet”, w);
if((param = req.getParameter(”dirToShow”)) == null)
if((param = getInitParameter(”dirToShow”)) == null)
{
w.println(”<H1><FONT COLOR=RED>” +
”The <EM>dirToShow</EM>
parameter required!</FONT></H1>”);
return;
}
File root = new File(param);
if(!root.isDirectory())
{
w.println(”<H1><FONT COLOR=RED>” +
”The parameter is not a directory or not exist!<
/FONT></H1>”);
return;
}
File[] fileList = root.listFiles();
w.println(”<H2><FONT COLOR=TEAL>” +
”Total number of files in the choosen directory - ” +
fileList.length + ”</FONT></H2>”);
w.println(”<H3><FONT COLOR=PURPLE>” +
”Directory path - ” + param + ”</FONT></H3><HR>”);
w.println(”<TABLE BORDER=0 CELLSPACING=5>”);
for(int i = 0; i < fileList.length; i++)
printName(fileList[i], w);
w.println(”</TABLE><HR>”);
generateFooter(w);
}
private void printName(File name, PrintWriter output)
{
String type = name.isDirectory()
? ” (Directory)” : ” (File)”;
output.println(”<TR><TD>” + type +
”</TD><TD><FONT COLOR=BLUE>”
+ name.getName() + ”</FONT></TD></TR>”);
}
private void generateHeader(String title, PrintWriter output)
{
output.println(”<HTML>\n<HEAD>\n<TITLE>” +
title + ”</TITLE>\n</HEAD>\n<BODY>”);
}
private void generateFooter(PrintWriter output)
{
output.println(”</BODY>\n</HTML>”);
output.flush();
output.close();
}
public String getServletInfo()
{
return ”This servlet shows a content of a directory” +
”mentioned in dirToShow parameter or property.”;
}
}
Мир ПК #04/99 |
| Справка | Условия | |
| В начало | Логин | Комментарий к колонке | Поиск | Почта |