4907

Клиент-серверные приложения на основе сервлетов

Практическая работа

Информатика, кибернетика и программирование

Клиент-серверные приложения на основе сервлетов Рассматривается методика построения Web-приложений на основе сервлетов. Приводятся примеры построения сервлетов в среде JBuilder и доставки (разворачивания) сервлетов на сервер Tomcat. 1.1. Базовая стр...

Русский

2012-11-29

220 KB

8 чел.

Клиент-серверные приложения на основе сервлетов

Рассматривается методика построения Web-приложений на основе сервлетов. Приводятся примеры построения сервлетов в среде JBuilder и доставки (разворачивания) сервлетов на сервер Tomcat.

1.1. Базовая структура и технология построения сервлетов

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

Для реализации сетевых взаимодействий на основе сервлетов в API Java включены пакеты javax.servlet и javax.servlet.http, предоставляющие классы и интерфейсы для функционирования сервлетов. В этих пакетах определяются два абстрактных класса GenericServlet и HttpServlet, при этом наиболее распространенным является последний, который и используется во всех приводимых ниже примерах. Ключевым методом в каждом сервлете является метод service, который принимает в качестве параметров объект ServletRequest и объект ServletResponse. Эти объекты предоставляют доступ к потокам ввода и вывода, что дает возможность сервлетам получать и отправлять данные. Метод service сначала определяет тип запроса, а потом вызывает метод doGet для реакции на запросы типа Get или метод doPost для реакции на запросы типа Post. Эти методы также определены в классе HttpServlet и переопределяются программистом при разработке сервлета. Первый из этих объектов содержит запрос, поступивший на сервер от клиента, а второй – передаваемый клиенту ответ. При каждом обращении к методам doGet или doPost в качестве аргументов принимаются объекты, которые реализуют интерфейсы HttpServletRequest и HttpServletResponse.

Эталонной реализацией стандартов для сервлетов и JSP-страниц является сервер Tomcat. В его состав входит Web-сервер, что позволяет использовать Tomcat либо как автономный контейнер для тестирования сервлетов и JSP-страниц, либо в качестве обработчика запросов сервлетов и JSP-страниц, принимаемых от других Web-серверов, в частности от Microsoft IIS.

      Создание и тестирование сервлета наиболее просто можно осуществить в интегрированной среде JBuilder. С этой целью необходимо выполнить следующую последовательность шагов.

  1.  Выбрать пункт меню File | New Project.
  2.  В панели Project Wizard Step 1 of 3 ввести в окно Name имя проекта (например, GetServlet), в окно Directory  имя рабочей папки (например, D:\T), убрать флажок у кнопки Generate Project notes file и нажать на кнопку Finish.
  3.  Выбрать пункт меню File | New.
  4.  В панели Object Gallery выбрать закладку Web, выделить тип приложения Servlet и нажать на кнопку OK.
  5.  В панели Servlet Wizard Step 1 of 5 ввести в окно Class Name имя класса сервлета (например  GetServlet) и нажать на кнопку Next (имя класса сервлета может в общем случае отличаться от имени проекта, однако для унификации во всех задачах настоящего пособия имя класса сервлета рекомендуется выбирать совпадающим с именем проекта).
  6.  В панели Servlet Wizard Step 2 of 5 установить флажок Generate SHTML file и нажать на кнопку Next.
  7.  В панели Servlet Wizard Step 3 of 5 обратить внимание на имя
    URL-адреса в окне URL pattern и нажать на кнопку Finish.

      В результате будет создан проект, включающий в себя файлы с расширением .java и .shtml (например, GetServlet.java и GetServlet.shtml), программный код которых необходимо модифицировать в соответствии с конкретным характером разрабатываемого сервлета.

1.2. Построение сервлетов в среде JBuilder

Обработка http-запросов GET. В качестве простейшего примера рассмотрим методику построения сервлета, реализующего посылку данных на сервер по методу GET. В примере на клиентской стороне в окно вводится некоторое имя, и данные отсылаются на сервер путем нажатия на кнопку типа submit.
В качестве отклика сервер посылает клиенту текстовую строку, в которую включено значение, введенное на клиентской стороне. Соответствующие формы реализованы в файле
GetServlet.shtml, программный код приложения содержится в файле GetServlet.java.

А. Проанализируйте структуру файлов и обратите внимание на
URL-адрес, задаваемый в атрибуте action файла GetServlet.shtml. В файле GetServlet.java обратите внимание на особенности использования методов setContentType и setCharacterEncoding, при помощи которых задается тип содержимого данных и их кодировка, а также на методы getParameter и
getWriter, первый из которых дает возможность получить данные, отправленные клиентом на сервер, а второй – обеспечить обратную посылку требуемой информации клиенту. Характер этой информации передается через объект out методом println, в результате работы которого формируется возвращаемый клиенту html-документ.

Б. Создайте проект с именем GetServlet согласно методике, изложенной в 1.1, включив в файлы GetServlet.java и GetServlet.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

 Сервлет GetServlet.java

// GetServlet.java.

package getservlet;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

 // класс сервлета

public class GetServlet extends HttpServlet {

 // обработка клиентских запросов Get

 protected void doGet(HttpServletRequest request, HttpServletResponse response)

                                   throws ServletException, IOException{

    response.setContentType("text/html; charset=windows-1251");

    request.setCharacterEncoding("Cp1251");

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

    PrintWriter out = response.getWriter();

    //начало html-документа

    out.println( "<html>" );

    out.println( "<head>" );

    out.println("<title> Обработка Get-запроса </title>" );

    out.println( "</head>" );

      // тело документа

     out.println( "<body bgcolor=\"#FFA07A\">" );

     out.println( "<h1> Привет,  " + firstName + ".<br>" );

     out.println( " Это ответ на Get-запрос! </h1>" );

     out.println( "</body>" );

     // конец html-документа

     out.println( "</html>" );

     out.close();  // закрытие потока

  }

}

 Исходный html-файл для вызова сервлета GetServlet.java

<!--GetServlet.shtml-->

<html>

<head>

 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

 <title>Обработка HTTP-запроса GET</title>

</head>

<body bgcolor = "#FDF5E6">

 <form action = "/getservlet" method = "get">

   <p> Введите Ваше имя и нажмите на кнопку "Послать" <br>

   <input type = "text" name = "firstname">

   <input type = "submit" value = "Послать"> </p>

 </form>

</body>

</html>

Контрольное задание 1.1. Составьте собственный вариант приложения GetServlet1, изменив фон возвращаемой страницы и заменив содержание посылаемой на клиентскую сторону строки на сообщение "Ваше имя, firstName, теперь нам известно" (firstName – имя, введенное клиентом). Протестируйте разработанный проект в среде JBuilder.

Обработка http-запросов Post. В качестве примера, реализующего посылку данных на сервер по методу POST, рассмотрим методику построения сервлета, в котором на клиентской стороне также в окно вводится некоторое имя, и данные отсылаются на сервер нажатием на кнопку типа submit. В качестве отклика сервер посылает клиенту текстовую строку, в которую включено значение, введенное на клиентской стороне. Соответствующие формы реализованы в файле PostServlet.shtml, программный код приложения содержится в файле PostServlet.java.

А. Проанализируйте структуру файлов и обратите внимание на URL-адрес, задаваемый в атрибуте action файла PostServlet.shtml. В файле PostServlet.java также используются методы getParameter и getWriter, первый из которых дает возможность получить данные, отправленные клиентом на сервер, а второй – обеспечить обратную посылку требуемой информации клиенту. Характер этой информации передается через объект out методом println, в результате работы которого формируется возвращаемый клиенту html-документ.

Б. Создайте проект с именем PostServlet согласно методике, изложенной
в 1.1, включив в файлы
PosServlet.java и PosServlet.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

  Сервлет PosServlet.java

// PostServlet.java.

package postservlet;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

// класс сервлета

public class PostServlet extends HttpServlet {

  // обработка клиентских запросов Post

 protected void doPost(HttpServletRequest request, HttpServletResponse response)

                                   throws ServletException, IOException{

    response.setContentType("text/html; charset=windows-1251");

    request.setCharacterEncoding("Cp1251");

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

    PrintWriter out = response.getWriter();

    //начало html-документа

    out.println( "<html>" );

    out.println( "<head>" );

    out.println("<title>Обработка Post-запроса</title>" );

    out.println( "</head>" );

    // тело документа

     out.println( "<body>" );

     out.println( "<p><font color=\"red\" size=\"+8\">Здравствуйте, "

                  + firstName + "!<br>" );

     out.println( " Ваш Post-запрос получен!</font></p>" );

     out.println( "</body>" );

     // конец html-документа

     out.println( "</html>" );

     out.close();  // закрытие потока

  }

}

 Исходный html-файл для вызова сервлета PostServlet.java

<!-- PostServlet.shtml-->

<html>

<head>

 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

 <title>Обработка HTTP-запроса POST</title>

</head>

<body bgcolor = "#F08080">

 <form action = "/postservlet" method = "post">

   <h3>Введите Ваше имя и нажмите на кнопку "Послать" </h3>

   <input type = "text" name = "firstname" >

   <input type = "submit" value = "Послать" >

 </form>

</body>

</html>

Контрольное задание 1.2. Составьте собственный вариант приложения PostServlet1, заменив содержание посылаемой на клиентскую сторону строки на сообщение "Ваше имя, firstName, будет занесено в базу данных" (firstName – имя, введенное клиентом). Измените цвет текста на возвращаемой странице. Протестируйте разработанный проект в среде JBuilder.

Обработка нескольких параметров, заданных именами. Если в форме содержится несколько объектов с различными именами, то обрабатывать ее можно многократным использованием функции getParameter с аргументами, определяемыми этими именами. Пример решения подобной задачи реализуется в приведенных далее файлах ParamServlet.shtml и ParamServlet.java, в которых осуществляется работа с тремя текстовыми окнами.

А. Проанализируйте структуру файлов и обратите внимание на URL-адрес в атрибуте action файла ParamServlet.shtml. В файле ParamServlet.java обратите внимание на трехкратное использование метода getParameter для получения данных, отправленных клиентом на сервер. Характер этих данных передается через объект out методом println, обратно на клиентскую сторону, где отображается в виде пронумерованного списка.

Б. Создайте проект с именем ParamServlet согласно методике, изложенной в 1.1, включив в файлы ParamServlet.java и ParamServlet.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

   Сервлет ParamServlet.java

// ParamServlet.java

package paramservlet;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

//  класс сервлета

public class ParamServlet extends HttpServlet {

  // обработка клиентских запросов Post

 public void doPost(HttpServletRequest request, HttpServletResponse response)

     throws ServletException, IOException {

     response.setContentType("text/html; charset=windows-1251");

     request.setCharacterEncoding("Cp1251");

     PrintWriter out = response.getWriter();

     String title = "Список параметров, отправленных клиентом на сервер";

      // начало html-документа

     out.println("<html>");

     out.println("<body bgcolor=\"#ADD8E6\">\n" +

                 "<h1 align=center>" + title + "</h1>\n");

     out.println("<ol>\n" +

         " <li><b>Имя</b>: " + request.getParameter("fname") + "</li>\n" +

         " <li><b>Фамилия</b>: " + request.getParameter("sname") + "</li>\n"+

         " <li><b>Возраст</b>: " + request.getParameter("age") + "</li>\n" +

                 "</ol>\n");

     //  конец html-документа

     out.println("</body></html>");

    // закрытие потока

     out.close();  

   }

}

     Исходный html-файл для вызова сервлета ParamServlet.java

<!-- ParamServlet.shtml-->

<html>

<head>

 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

 <title>Обработка HTTP - запроса POST</title>

</head>

<body bgcolor = "#C0C0C0">

<h1 align="center">Ввод трех параметров</h1>

 <form action = "/paramservlet" method = "post">

   <h3>Введите параметры и нажмите на кнопку "Послать" </h3>

   Имя       <input type = "text" name = "fname"><br>

   Фамилия   <input type = "text" name = "sname"><br>

   Возраст   <input type = "text" name = "age"><br><br>

   <center>

      <input type = "submit" value = "Послать" >

   </center>

 </form>

</body>

</html>

Контрольное задание 1.3. Составьте собственный вариант проекта ParamServlet1, дополнив приложение еще одним текстовым окном для ввода номера телефона. Организуйте обратную посылку на клиентскую сторону, наряду с другой информацией, введенного номера телефона и измените фон возвращаемой клиенту страницы. Протестируйте разработанный проект в среде JBuilder.

Обработка списка выбора. Рассмотрим методику построения сервлета, реализующего работу со списком выбора. Такой список формируется в файле SelectServlet.shtml, где также проводится инициализация элементов списка. Значение выбранного элемента после нажатия на кнопку submit отсылается на сервер, где в файле SelectServlet.java при помощи метода
getParameter это имя обрабатывается для формирования ответного html-документа.

А. Проанализируйте структуру файлов и обратите внимание на способ формирования списка в файле SelectServlet.shtml. В файле SelectServlet.java обратите внимание на использование методов getParameter и getWriter, первый из которых дает возможность получить данные, отправленные клиентом на сервер, а второй – обеспечить обратную посылку требуемой информации клиенту. Характер этой информации передается через объект out методом println, в результате работы которого формируется возвращаемый клиенту html-документ.

Б. Создайте проект с именем SelectServlet согласно методике, изложенной в 1.1, включив в файлы SelectServlet.java и SelecttServlet.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

  Сервлет SelectServlet.java

// SelectServlet

package selectservlet;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

//  класс сервлета

public class SelectServlet extends HttpServlet {

  // обработка клиентских запросов Post

 public void doPost(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException {

   response.setContentType("text/html; charset=windows-1251");

   request.setCharacterEncoding("Cp1251");

   String sb = request.getParameter("subject");

   PrintWriter pw = response.getWriter();

    // начало html-документа

   pw.println("<html>");

   pw.println( "<head>" );

   pw.println("<title>Выбор предмета</title>" );

   pw.println( "</head>" );

   pw.println( "<body bgcolor=#DDDDDD>\n");

   pw.println("<h2>Выбран предмет:  " + sb  + "</h2>");

   pw.println("</body>");

   pw.println("</html>");

   pw.close();  // закрытие потока

 }

}

    Исходный html-файл для вызова сервлета SelectServlet.java

<!-- SelectServlet.shtml-->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

       <title>Список выбора</title>

</head>

<body bgcolor="#FAFAD2">

<center>

<form    method="post" action="/selectservlet">

 <b>Выбор предмета:</b>

 <select name="subject" size="1">

 <option value="Математика">Математика</option>

 <option value="Физика">Физика</option>

 <option value="Информатика">Информатика</option>

 <option value="Программирование">Программирование</option>

 </select>

 <br><br>

 <input type=submit value="Послать">

</form>

</center>

</body>

</html>

Контрольное задание 1.4. Составьте собственный вариант проекта SelectServlet1, дополнив список еще одним элементом для ввода имени предмета, и измените фон исходной html-страницы. Протестируйте разработанный проект в среде JBuilder.

Обработка произвольного числа параметров. Если в форме содержится произвольное число объектов с различными именами, то они могут обрабатываться без использования функции getParameter с фиксированными аргументами для каждого имени. Пример решения подобной задачи при помощи организации цикла реализуется в файлах AllParameters.shtml и AllParameters.java, в которых осуществляется обработка сложной формы с различными типами компонентов.

А. Проанализируйте структуру файлов и обратите внимание на использование метода getParameterNames. При помощи этого метода создается объект paramNames класса Enumeration, представляющий собой перечисление имен всех элементов формы, которая создается в файле AllParameters.shtml. Через объект paramNames вызавается метод hasMoreElements, который возвращает значение true до тех пор, пока в перечислении содержатся имена элементов формы. Очередное имя элемента вызывается в цикле методом nextElement и для каждого имени методом getParameter определяется его значение. Найденные пары имя-значение отсылаются на клиентскую сторону в табличной форме при помощи метода println. Особенностью приложения является возможность его запуска как методом doGet, так и при помощи метода doPost.

Б. Создайте проект с именем AllParameters согласно методике, изложенной в 1.1, включив в файлы AllParameters.java и AllParameters.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

  Сервлет AllParameters.java

// AllParameters.java

package allparameters;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

//  класс сервлета

public class AllParameters extends HttpServlet {

  // обработка клиентских запросов Get

 public void doGet(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

    response.setContentType("text/html; charset=windows-1251");

    request.setCharacterEncoding("Cp1251");

    PrintWriter out = response.getWriter();

    String title = " Чтение всех параметров";

      // начало html-документа

    out.println("<html>");

    out.println( "<body bgcolor=\"#F08080\">\n" +

                 "<h1 align=center>" + title + "</h1>\n" +

                 "<table  border=1 align=center>\n" +

                 "<tr bgcolor=\"yellow\">\n" +

                 "<th>Имя параметра</th>\n" +

                 "<th>Значение параметра</th></tr>");

    Enumeration paramNames = request.getParameterNames();

    while(paramNames.hasMoreElements()) {

        String paramName = (String)paramNames.nextElement();

        out.print("<tr bgcolor=\"#ADD8E6\"><td>" + paramName + "</td>\n");

        String paramValue = request.getParameter(paramName);

        out.println("<td>");

        if (paramValue.length() == 0)

                 out.println("<i>Нет значений</i>");

        else

                 out.println(paramValue);

        }

    out.println("</td></tr></table>\n</body></html>");

 }

// обработка клиентских запросов Post

 public void doPost(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException {

   doGet(request, response);

 }

}

  Исходный html-файл для вызова сервлета AllParameters.java

<!-- AllParameters.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

              <title>Пример сложной формы</title>

</head>

<body bgcolor="#E0FFFF">

<h1 align="center">Пример сложной формы</h1>

<form action="/allparameters" method="POST">

  Индекс товара : <input type="text" name="itemNum"><br>

  Количество: <input type="text" name="quantiti"><br>

  Цена: <input type="text" name="price" value=""><br><hr>

  Имя: <input type="text" name="firstname"><br>

  Фамилия: <input type="text" name="lastname"><br>

  Адрес: <textarea name="address" rows=3 cols=40></textarea><br>

  Кредитная карта:<br>

  <input type="radio" name="cardtype" value="Visa">Visa<br>

  <input type="radio" name="cardtype" value="Master Card">Master Card<br>

  <input type="radio" name="cardtype" value="Amex">American Express<br>

  <input type="radio" name="cardtype" value="Discover">Discover<br>

  <input type="radio" name="cardtype" value="Java SmartCard">SmartCard<br>

  Номер карты: <input type="password" name="cardNum"><br>

  <center>

    <input type="submit" value="Послать заказ">

  </center>

</form>

</body>

</html>

Контрольное задание 1.5. Составьте собственный вариант проекта AllParameters1, дополнив форму еще одним элементом для ввода номера телефона и изменив фон исходной html-страницы. Протестируйте разработанный проект в среде JBuilder.

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

А. Проанализируйте структуру файлов AllParamList.java и AllParamList.shtml и обратите внимание на оператор объявления и инициализации массива String[] paramValues. Если в этом массиве содержится единственный элемент, то обработка выполняется таким же способом, как и в предыдущей задаче. Однако в случае наличия в массиве двух элементов характер обработки изменяется и в таблице создается неименованный список для вывода двух строк. Найденные пары имя-значение отсылаются на клиентскую сторону в табличной форме методом println.

Б. Создайте проект с именем AllParamList согласно методике, изложенной в 1.1, включив в файлы AllParamList.java и AllParamList.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

 Сервлет AllParamList.java

// AllParamList.java

package allparamlist;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

//  класс сервлета

public class AllParamList extends HttpServlet {

  // обработка клиентских запросов Get

 public void doGet(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

    response.setContentType("text/html; charset=windows-1251");

    request.setCharacterEncoding("Cp1251");

    PrintWriter out = response.getWriter();

    String title = "Пример формы  c выводом списка в таблицу";

     // начало html-документа

    out.println("<html>");

    out.println( "<body bgcolor=\"#F08080\">\n" +

                 "<h1 align=center>" + title + "</h1>\n" +

                 "<table  border=1 align=center>\n" +

                 "<tr bgcolor=\"yellow\">\n" +

                 "<th>Имя параметра</th>\n" +

                 "<th>Значение параметра</th></tr>");

    Enumeration paramNames = request.getParameterNames();

    while(paramNames.hasMoreElements()) {

          String paramName = (String)paramNames.nextElement();

          out.print("<tr bgcolor=\"#ADD8E6\"><td>" + paramName + "</td>\n");

          String[] paramValues = request.getParameterValues(paramName);

          out.println("<td>");

          if (paramValues.length == 1) {

             String paramValue = paramValues[0];

             if (paramValue.length() == 0)

                 out.println("<i>Нет значений</i>");

             else

                 out.println(paramValue);

           }

           else {

              out.println("<ul>");

              for(int i=0; i<paramValues.length; i++) {

                out.println("<li>" + paramValues[i]);

              }

              out.println("</ul>");

            }

     }

     out.println("</td></tr></table>\n</body></html>");

 }

  // обработка клиентских запросов Post

 public void doPost(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException {

   doGet(request, response);

 }

}

   Исходный html-файл для вызова сервлета AllParamList.java

<!-- AllParamList.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

              <title>Пример формы c выводом списка в таблицу</title>

</head>

<body bgcolor="#E0FFFF">

<h1 align="center">Пример формы c выводом списка в таблицу</h1>

<form action="/allparamlist" method="POST">

  Индекс товара : <input type="text" name="itemNum"><br>

  Количество: <input type="text" name="quantiti"><br>

  Цена: <input type="text" name="price" value=""><br><hr>

  Имя: <input type="text" name="firstname"><br>

  Фамилия: <input type="text" name="lastname"><br>

  Адрес: <textarea name="address" rows=3 cols=40></textarea><br>

  Кредитная карта:<br>

  <input type="radio" name="cardtype" value="Visa">Visa<br>

  <input type="radio" name="cardtype" value="Master Card">Master Card<br>

  <input type="radio" name="cardtype" value="Amex">American Express<br>

  <input type="radio" name="cardtype" value="Discover">Discover<br>

  <input type="radio" name="cardtype" value="Java SmartCard">SmartCard<br>

  Номер карты: <input type="password" name="cardNum"><br>

  Повторный ввод номера карты:

  <input type="password" name="cardNum"><br><br>

  <center>

     <input type="submit" value="Послать заказ">

  </center>

</form>

</body>

</html>

Контрольное задание 1.6. Составьте собственный вариант проекта AllParamList1, дополнив форму элементами для ввода номера телефона и адреса e-mail, изменив фон возвращаемой html-страницы. Протестируйте разработанный проект в среде JBuilder.

Отслеживание сеанса. Рассмотрим методику построения сервлета, при помощи которого отслеживается сеанс работы с сайтом и выводится необходимая информация о таком сеансе – идентификатор сессии, время создания сессии, время последнего посещения, число предыдущих посещений.

А. Проанализируйте структуру приведенных файлов AccessInfo.java и AccessInfo.shtml, обратив внимание на строку, в которой создается ссылка сount класса Integer. Поскольку аргументу функции getValue при первом посещении сайта соответствует нулевое значение, то ссылка сount также получает значение null. При этом в условном операторе работает ветвь if и создается объект класса Integer, соответствующий нулевому значению переменной типа int. Одновременно формируется строка для формирования текстового сообщения "Приветствуем нового посетителя нашего сайта!". После завершения работы метода putValue("accessCount",сount) первому аргументу будет соответствовать ненулевое значение второго аргумента и при повторном посещении сайта в условном операторе будет выполняться ветвь else. Поэтому подготавливается переменная для сообщения "Мы снова приветствуем Вас!" и увеличивается на единицу переменная сount. Характер полученной информации передается клиенту через объект out методом println, и в результате в табличной форме формируется возвращаемый html-документ.

Б. Создайте проект с именем AccessInfo согласно методике, изложенной
в 1.1, включив в файлы
AccessInfo.java и AccessInfo.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

  Сервлет AccessInfo.java

// AccessInfo.java

package accessinfo;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.net.*;

import java.util.*;

//  класс сервлета

public class AccessInfo extends HttpServlet {

   // обработка клиентских запросов Get

 public void doGet(HttpServletRequest request, HttpServletResponse response)

                         throws ServletException, IOException {

   response.setContentType("text/html; charset=windows-1251");

   request.setCharacterEncoding("Cp1251");

   PrintWriter out = response.getWriter();

   String title = "Пример отслеживания сеанса";

   HttpSession session = request.getSession(true);

   String heading;

   Integer сount = (Integer)session.getValue("accessCount");

   if (сount == null) {

      сount = new Integer(0);

      heading = "Приветствуем нового посетителя  нашего сайта!";

     }

   else {

      heading = "Мы снова приветствуем Вас!";

      сount = new Integer(сount.intValue() + 1);

      }

   session.putValue("accessCount", сount);

   // начало html-документа

   out.println( "<html><body bgcolor=\"#FDF5E6\">\n" +

        "<h1 align=\"center\">" + heading + "</h1>\n" +

        "<h2>Информация о Вашей сессии:</h2>\n" +

        "<table border=1 align=\"center\">\n" +

        "<tr bgcolor=\"#FFAD00\">\n" +

          "<th>Тип информации</th>\n" +

          "<th>Значение</th></tr>\n" +

        "<tr>\n" +

          "<td>ID</td>\n" +

          "<td>" + session.getId() + "</td></tr>\n" +

        "<tr>\n" +

          "<td>Время создания</td>\n" +

          "<td>" + new Date(session.getCreationTime()) + "</td></tr>\n" +

        "<tr>\n" +

          "<td>Время последнего посещения</td>\n" +

          "<td>" + new Date(session.getLastAccessedTime()) + "</td></tr>\n" +

        "<tr>\n" +

          "<td>Число предыдущих посещений</td>\n" +

          "<td>" + сount + "</td></tr>\n" +

        "</table>\n" +

        "<h2>Для обновления информация вызвать  AccessInfo.shtml</h2>" +

        "</body></html>");

      }

   // идентичная обработка Get и Post-запросов.

 public void doPost(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException {

   doGet(request, response);

   }

}

     Исходный html-файл для вызова сервлета AccessInfo.java

<!-- AccessInfo.shtml -->

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

<title>

    Отслеживание сеансов посещений

</title>

</head>

<body bgcolor="#E0FFFF">

<form action="/accessinfo" method="post">

<h3>Нажмите на кнопку Получить для получения информации о сессии</h3>

<p><input type="submit" name="Submit" value="Получить"></p>

</form>

</body>

</html>

Контрольное задание 1.7. Составьте собственный вариант приложения AccessInfo1, изменив фон исходной и возвращаемой html-страниц. Измените также по своему усмотрению текст сообщений, передаваемых клиенту при первом и повторных посещениях сайта. Протестируйте разработанный проект в среде JBuilder.

Файлы, хранимые на сервере. Рассмотрим задачу создания хранимого на сервере файла, в котором содержится информация о результатах опроса посетителей сайта. После создания объекта класса File осуществляется чтение существующих ответов, затем определяется выбранный ответ и обновляются итоги опроса.

А. Проанализируйте структуру файлов FileServlet.java и FileServlet.shtml и обратите внимание на структуру операторов чтения существующих ответов в массив lang и вывода обновленного значения массива lang в файл. Проанализируйте создаваемый сервлетом html-документ и обратите внимание на способ формирования выходной информации при помощи объекта класса StringBuffer, что позволяет использовать метод println единственный раз.

Б. Создайте проект с именем FileServlet согласно методике, изложенной в 1.1, включив в файлы FileServlet.java и FileServlet.shtml приводимый далее программный код. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

  Сервлет FileServlet.java

// FileServlet.java

package fileservlet;

import javax.servlet.*;

import javax.servlet.http.*;

import java.text.*;

import java.io.*;

//  класс сервлета

public class FileServlet extends HttpServlet {

  private String langNames[] =

     { "C++", "C#", "Java", "Pascal", "VBasic" };

   // обработка клиентских запросов Post

  public void doPost(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException{

     response.setContentType("text/html; charset=windows-1251");

     int lang[] = null, total = 0;

     File f = new File( "data.dat" );

     if ( f.exists() ) {

        // чтение существующих ответов

        try {

           ObjectInputStream input = new ObjectInputStream(

                new FileInputStream( f ) );

           lang = (int []) input.readObject();

           input.close();   // закрытие потока

           for ( int i = 0; i < lang.length; ++i )

              total += lang[ i ];

           }

        catch( ClassNotFoundException cnfe ) {

           cnfe.printStackTrace();

          }

       }

     else

        lang = new int[ 5 ];

     // получение текущего ответа

     String value =  request.getParameter( "lng" );

     ++total;   // увеличение счетчика всех ответов

     // определение выбранного ответа и обновление итогов

     for ( int i = 0; i < langNames.length; ++i )

        if ( value.equals( langNames[ i ] ) )

           ++lang[ i ];

     // вывод обновленного значения массива lang в файл

     ObjectOutputStream output = new ObjectOutputStream(

                           new FileOutputStream( f ) );

     output.writeObject( lang );

     output.flush();

     output.close();

     // вычисление процентного соотношения ответов

     double percentages[] = new double[ lang.length ];

     for ( int i = 0; i < percentages.length; ++i )

        percentages[ i ] = 100.0 * lang[ i ] / total;

     PrintWriter out = response.getWriter();

     StringBuffer buf = new StringBuffer();

      // начало html-документа

     buf.append( "<html>\n" );

     buf.append( "<title>Обработка ответов участников опроса</title>\n" );

     buf.append( "<body bgcolor=\"#E0FFFF\">\n");

     buf.append( "<h3>Результаты опроса:</h3><pre>" );

     DecimalFormat twoDigits = new DecimalFormat( "#0.00" );

     for ( int i = 0; i < percentages.length; ++i ) {

        buf.append( "<br>" );

        buf.append( langNames[ i ] );

        buf.append( ": " );

        buf.append( twoDigits.format( percentages[ i ] ) );

        buf.append( "%  всех ответов: " );

        buf.append( lang[ i ] );

        buf.append( "\n" );

     }

     buf.append( "\n<br>Общее число участников опроса: " );

     buf.append( total );

     buf.append( "</pre>\n</body></html>" );

     out.println( buf.toString() );

     out.close();

  }

}

   Исходный html-файл для вызова сервлета FileServlet.java

<!-- FileServlet.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

       <title>Вывод результатов опроса в файл</title>

</head>

<body bgcolor="#FAFAD2">

<form    method="post" action="/fileservlet">

<h3> Какой язык программирования Вы используете?</h3>

 <input type="radio" name="lng" value="C++" checked>C++<br>

 <input type="radio" name="lng" value="C#">C#<br>

 <input type="radio" name="lng" value="Java">Java<br>

 <input type="radio" name="lng" value="Pascal">Pascal<br>

 <input type="radio" name="lng" value="VBasic">VBasic<br><br>

 <input type="submit" value="Послать">

 <input type="reset" value="Очистить">

</form>

</body>

</html>

Контрольное задание 1.8. Составьте собственный вариант приложения FileServlet1, включив в форму дополнительную радиокнопку для обработки информации об использовании языка Perl. Введите необходимые изменения в файл FileServlet.java и выберите другой фон исходной и возвращаемой html-страниц. Протестируйте разработанный проект в среде JBuilder.

Контроль данных сеанса. Рассмотрим методику построения сервлета, при помощи которого осуществляется контроль данных сеанса работы с сайтом. При запуске сервлета создается объект session класса HttpSession пользовательского сеанса или создается новый сеанс, если он не существует. Сервлет добавляет выбранный пользователем язык программирования и наименования рекомендуемых литературных источников в сеанс, после чего отправляет на клиентскую сторону html-документ с необходимой информацией. Эту информацию можно получить в любое время существования сеанса путем вызова файла Books.shtml.

А. Проанализируйте структуру приведенных в рассматриваемом примере файлов SessionServlet.java, SessionServlet.shtml и Books.shtml. Обратите внимание на использование в сервлете двух методов обработки клиентских запросов – doPost и doGet. Первый вызывается при использовании файла
SessionServlet.shtml, и именно в этом методе формируется объект пользовательского сеанса session при первом обращении к сайту. Второй метод вызывается при запуске файла Books.shtml с целью получения информации о рекомендуемой литературе, и здесь используется ранее созданный объект
session. Каждый из этих методов формирует возвращаемый html-документ.

Б. Создайте проект с именем SessionServlet согласно методике, изложенной в 1.1, включив в файлы SessionServlet.java и SessionServlet.shtml приводимый далее программный код. Для включения в проект файла Books.shtml создайте второй сервлет с именем класса Books и включите в файл Books.shtml приводимый далее программный код. Поскольку файл Books.java второго сервлета в дальнейшем не используется, его можно удалить из проекта. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

  Сервлет SessionServlet.java

// SessionServlet.java

package sessionservlet;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

//  класс сервлета

public class SessionServlet extends HttpServlet {

 private final static String names[] = { "C++", "C#", "Java", "Pascal",

                                         "Visual Basic 6" };

 private final static String books[] = {

    "Г. Шилдт. Самоучитель С++",

    "А. Гарнаев. Самоучитель Visual Studio .NET 2003.",

    "Х. М. Дейтел, П. Дж. Дейтел. Как программировать на Java",

    "Н. Б. Кулибин. Программирование в Turbo Pascal 7.0.",

    "Д. Коннэлл. Visual Basic 6" };

  // обработка клиентских запросов Post

  public void doPost(HttpServletRequest request, HttpServletResponse response)

                     throws ServletException, IOException {

    String lang = request.getParameter( "lng" );

    response.setContentType("text/html; charset=windows-1251");

     // получение  пользовательского объекта сеанса

    //если он не существует - создание сеанса (значение аргумента true)

    HttpSession session = request.getSession( true );

    // добавление  выбранного значения  в  сеанс

    session.putValue( lang, getBooks( lang ) );

    PrintWriter out = response.getWriter();;

      //  начало html-документа

    out.println(  "<html><head><title>" );

    out.println( " Применение Sessions" );

    out.println( "</title></head><body bgcolor=\"#FFC0CB\">" );

    out.println( "<h3>Изучаем использование Sessions!<h3>" );

    out.println( "Выбранный Вами язык программирования " +  lang);

    out.println( "  - это замечательный язык!<br>" );

    out.println( " Для получения информации о литературе " +

                 "вызовите файл Books.shtml" );

    out.println( "</body></html>" );

    out.close();

  }

   // обработка клиентских запросов Get

  public void doGet(HttpServletRequest request, HttpServletResponse response)

                     throws ServletException, IOException {

    response.setContentType("text/html; charset=windows-1251");

     // получение пользовательского объекта сеанса

    // не создавать сеанс, если он не существует (значение аргумента false)

    HttpSession session = request.getSession( false );

    // получение имен значений сеанса

    String valueNames[];

    if ( session != null )

       valueNames = session.getValueNames();

    else

       valueNames = null;

    PrintWriter out = response.getWriter();

      // начало html-документа

    out.println(  "<html><head><title>"  );

    out.println( "Использование Sessions " );

    out.println( "</title></head><body bgcolor=\"#E0FFFF\">"  );

    if ( valueNames != null && valueNames.length != 0 ) {

       out.println( "<h1>Рекомендуемая литература</h1>"  );

       // получение значения для каждого имени в valueNames

       for ( int i = 0; i < valueNames.length; i++ ) {

          String value =

             (String) session.getValue( valueNames[ i ] );

          out.println("Язык программирования:  "+

             valueNames[ i ] + " <br>  " +  value +  "<br><br>" );

        }

     }

     else {

        out.println( "<h1>Рекомендации отсутствуют</h1>" );

        out.println( "Вы не выбрали язык программирования" );

     }

     out.println( "</body></html>" );

     out.close();

  }

    // получение информации о литературе

  private String getBooks( String lang )

  {

     for ( int i = 0; i < names.length; ++i )

        if ( lang.equals( names[ i ] ) )

           return books[ i ];

     return "";  // не найдена соответствующая строка

  }

}

     Исходный html-файл для вызова сервлета SessionServlet.java

<!-- SessionServlet.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

       <title>Применение Session </title>

</head>

<body bgcolor="#00FFFF">

<form    method="post" action="/sessionservlet">

<h3> Какой язык программирования Вас интересует?</h3>

 <input type="radio" name="lng" value="C++" checked>C++<br>

 <input type="radio" name="lng" value="C#">C#<br>

 <input type="radio" name="lng" value="Java">Java<br>

 <input type="radio" name="lng" value="Pascal">Pascal<br>

 <input type="radio" name="lng" value="Visual Basic 6">Visual Basic 6<br>

 <center>

   <input type="submit" value="Послать">

   <input type="reset" value="Очистить">

 </center>

</form>

</body>

</html>

     Дополнительный html-файл для вызова сервлета SessionServlet.java 

<!-- Books.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

<title> Использование Session</title>

</head>

<body bgcolor="#FFDAB9">

<form action="/sessionservlet"  method="GET">

  Нажмите на кнопку Рекомендуемая литература <br><br>

<input type=submit value="Рекомендуемая литература">

</form>

</body>

</html>

Контрольное задание 1.9. Составьте собственный вариант приложения SessionServlet1, включив в форму дополнительную радиокнопку для обработки информации об использовании языка Perl. Введите необходимые изменения в файл SessionServlet.java, указав в качестве дополнительной литературы источник "Х. М. Дейтел, П. Д. Дейтел, Т. З. Нието. Как программировать на Perl", и выберите другой фон исходной html-страницы. Протестируйте разработанный проект в среде JBuilder.

Хранение информации при помощи файлов cookie. Рассмотрим методику хранения информации на компьютере клиента при помощи файлов cookie.
В отличие от рассмотренного ранее способа хранения данных при помощи объектов класса HttpSession, использование файлов cookie позволяет сохранять данные в течение времени, задаваемого программистом при создании приложения. Если установленное время не истекло, данные сохраняются как в течение текущего, так и во время последующих сеансов. Установка времени реализуется при помощи метода setMaxAge, единственный аргумент которого задает время существования cookie в секундах. В рассматриваемом примере получение информации, сохраняемой в cookie, осуществляется путем вызова файла Books.shtml.

А. Проанализируйте структуру приведенных в рассматриваемом примере файлов CookieServlet.java, CookieServlet.shtml и Books.shtml. Обратите внимание на использование в сервлете двух методов обработка клиентских запросов – doPost и doGet. Первый из указанных методов вызывается при использовании файла CookieServlet.shtml и в этом методе формируется объект класса Cookie, аргументы которого задают имя cookie (lang) и значение cookie, получаемое при помощи метода getBooks. Второй метод вызывается при запуске файла Books.shtml с целью получения данных cookie о рекомендуемой литературе и здесь создается массив объектов cookies[] класса Cookie. В этот массив записываются имена всех клиентских cookie. Каждый метод обработки клиентских запросов формирует возвращаемый html-документ.

Б. Создайте проект с именем CookieServlet согласно методике, изложенной в 1.1, включив в файлы CookieServlet.java и CookieServlet.shtml приводимый далее программный код. Для включения в проект файла Books.shtml создайте второй сервлет с именем класса Books и поместите в файл Books.shtml приведенный в примере программный код. Поскольку файл Books.java второго сервлета в дальнейшем не используется, его можно удалить из проекта. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

 Сервлет CookieServlet.java

// CookieServlet.java

package cookieservlet;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

//  класс сервлета

public class CookieServlet extends HttpServlet {

 private final static String names[] = { "C++", "C#", "Java","Pascal",

                                         "Visual Basic 6" };

 private final static String books[] = {

    "Г. Шилдт. Самоучитель С++",

    "А. Гарнаев. Самоучитель Visual Studio .NET 2003.",

    "Х. М. Дейтел, П. Дж. Дейтел. Как программировать на Java",

    "Н. Б. Кулибин. Программирование в Turbo Pascal 7.0.",

    "Д. Коннэлл. Visual Basic 6" };

      // обработка клиентских запросов Post

 public void doPost(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

    String lang = request.getParameter( "lng" );

    response.setContentType("text/html; charset=windows-1251");

    Cookie c = new Cookie( lang, getBooks( lang ) );

    c.setMaxAge( 120 );  // время в секундах до удаления oookie

    response.addCookie( c );

    PrintWriter out = response.getWriter();

    // отправка html страницы клиенту

    out.println( "<html><head><title>" );

    out.println( "Применение Cookies" );

    out.println( "</title></head><body bgcolor=\"#FFF0F5\">" );

    out.println( "<h3>Изучаем использование Cookies!</h3>" );

    out.println( "Выбранный Вами язык программирования " +  lang);

    out.println( " - это замечательный язык!<br>" );

    out.println( "Для получения информации о литературе " +

                "вызовите файл Books.shtml" );

    out.println( "</body></html>" );

    out.close();

 }

   // обработка клиентских запросов Get

 public void doGet(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException {

    response.setContentType("text/html; charset=windows-1251");

    Cookie cookies[];

    cookies = request.getCookies(); // получение клиентских cookie

    PrintWriter out = response.getWriter();

    out.println( "<html><head><title>" );

    out.println( "Использование Cookies " );

    out.println( "</title></head><body bgcolor=\"#E0FFFF\">" );

    if ( cookies != null && cookies.length != 0 ) {

       out.println( "<h1>Рекомендуемая литература</h1>" );

       // получение имен всех cookie

       for ( int i = 0; i < cookies.length; i++ )

          out.println("Язык программирования:  "  +

                      cookies[ i ].getName() +  " <br> " +

                      cookies[ i ].getValue() + "<br><br>" );

    }

    else {

       out.println( "<h1>Рекомендации отсутствуют</h1>" );

       out.println( "Вы не выбрали язык программирования" );

       out.println( "или время жизни файла cookie истекло." );

    }

    out.println( "</body></html>" );

    out.close();

 }

    // получение информации о литературе

 private String getBooks( String lang )  {

    for ( int i = 0; i < names.length; ++i )

       if ( lang.equals( names[ i ] ) )

          return books[ i ];

    return "";  // не найдена соответствующая строка

 }

}

   Исходный html-файл для вызова сервлета CookieServlet.java

<!-- CookieServlet.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

       <title>Применение cookie </title>

</head>

<body bgcolor="#FAFAD2">

<form    method="post" action="/cookieservlet">

 <h3> Какой язык программирования Вас интересует?</h3>

 <input type="radio" name="lng" value="C++" checked>C++<br>

 <input type="radio" name="lng" value="C#">C#<br>

 <input type="radio" name="lng" value="Java">Java<br>

 <input type="radio" name="lng" value="Pascal">Pascal<br>

 <input type="radio" name="lng" value="Visual Basic 6">Visual Basic 6<br>

 <center>

   <input type="submit" value="Послать">

   <input type="reset" value="Очистить">

 </center>

</form>

</body>

</html>

    Дополнительный html-файл для вызова сервлета CookieServlet.java 

<!-- Books.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

       <title>Применение cookie </title>

</head>

<body bgcolor="#E0FFFF">

<form action="/cookieservlet"  method="GET">

  Нажмите на кнопку Рекомендуемая литература <br><br>

<input type=submit value="Рекомендуемая литература">

</form>

</body>

</html>

Контрольное задание 1.10. Составьте собственный вариант приложения CookieServlet1, включив в форму дополнительную радиокнопку для обработки информации об использовании языка Perl. Введите необходимые изменения в файл CookieServlet.java, указав в качестве дополнительной литературы источник " Х. М. Дейтел, П. Д. Дейтел, Т. З. Нието. Как программировать на Perl", и выберите другой фон возвращаемой html-страницы. Протестируйте разработанный проект в среде JBuilder.

Работа с базами данных. В примере приводится методика построения трехуровневого распределенного приложения, реализующего гостевую книгу и включающего в себя интерфейс пользователя, бизнес-логику и средства доступа к базам данных. Интерфейс пользователя реализуется при помощи отображаемого в браузере html-файла, бизнес-логика реализуется в сервлете, а организация взаимодействия с базами данных осуществляется через интерфейс JDBC, который обеспечивает единообразие при обращении к ним программ на Java. При этом работа с базами данных организуется при помощи запросов языка SQL, а все вопросы взаимодействия с различными системами управления базами данных берут на себя средства JDBC.

А. Проанализируйте приведенные далее файлы DataBaseServlet.java и DataBaseServlet.shtml и обратите внимание на структуру метода init, который вызывается за время существования сервлета единственный раз. Метод осуществляет соединение с базой данных Microsoft Access путем загрузки драйвера JdbcOdbcDriver и создания объекта connect класса Connection. При этом осуществляется соединение с базой данных Guests.mdb, зарегистрированной в качестве источника данных ODBC с именем Guests. В методе doPost обратите внимание на форматирование строки, являющейся аргументом метода insertIntoDB, при вызове которого выполняется вставка записей в базу данных при помощи оператора INSERT INTO.

Б. Создайте проект с именем DataBaseServlet согласно методике, изложенной в 1.1, включив в файлы DataBaseServlet.java и DataBaseServlet.shtml приводимый далее программный код. Поместите в произвольную папку базу данных Guests.mdb и зарегистрируйте ее в качестве источника данных ODBC с именем Guests, перейдя в каталог Источники данных (ODBC) Проводника. Откомпилируйте и запустите проект для опытного тестирования в среде JBuilder.

  Сервлет DataBaseServlet.java

// DataBaseServlet.java

package databaseservlet;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

import java.sql.*;

//  класс сервлета

public class DataBaseServlet extends HttpServlet {

  private Connection connect = null;

  private Statement state = null;

    // инициализация сервлета

  public void init( ServletConfig config )

     throws ServletException

  {

     super.init( config );

     try {

        Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );

        connect =

           DriverManager.getConnection( "jdbc:odbc:Guests", "", "" );

     }

     catch ( Exception e ) {

        e.printStackTrace();

        connect = null;

     }

  }

     // обработка клиентских запросов Post

  public void doPost(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

     String email, firstName, lastName, company, cb1, cb2, cb3, cb4;

     response.setContentType("text/html; charset=windows-1251");

     request.setCharacterEncoding("Cp1251");

     email = request.getParameter( "Email" );

     firstName = request.getParameter( "FirstName" );

     lastName = request.getParameter( "LastName" );

     company = request.getParameter( "Company" );

     cb1 = request.getParameter( "C_cpp" );

     cb2 = request.getParameter( "C_sh" );

     cb3 = request.getParameter( "Java" );

     cb4 = request.getParameter( "VB6" );

     PrintWriter output = response.getWriter();

    // отправка html-страницы клиенту

     if ( email.equals( "" ) ||

         firstName.equals( "" ) ||

         lastName.equals( "" ) ) {

       output.println( "<h3> Вы не заполнили все поля. " +

          "Нажмите на кнопку Back и заполните необходимые поля.</h3>");

       output.close();

       return;

     }

     boolean success = insertIntoDB( "'" + email + "','" + firstName + "','" +

         lastName + "','" + company + "','" +

       ( cb1 != null ? "yes" : "no" ) + "','" +

       ( cb2 != null ? "yes" : "no"  ) + "','" +

       ( cb3 != null ? "yes" : "no"  ) + "','" +

       ( cb4 != null ? "yes" : "no"  ) + "'"  );

    if ( success ){

      output.println( "<html><head><title>" );

      output.println( "Отчет о работе с базой данных " );

      output.println( "</title></head><body bgcolor=\"#FFA07A\">");

      output.print( "<h3>Спасибо,  " + firstName + ", за регистрацию.</h3>");

      output.print( "<h3>Ваши данные занесены в базу данных Guests.</h3>");

       }

    else

        output.print( "<h2> Ошибка. " +

                   "Пожалуйста, попытайтесь повторить ввод данных .</h2>");

    output.close();

  }

    // вставка записей в базу данных

  private boolean insertIntoDB( String stringtoinsert )

  {

     try {

        state = connect.createStatement();

        state.execute(

           "INSERT INTO Guests values (" + stringtoinsert + ");" );

        state.close();

     }

     catch ( Exception e ) {

        System.err.println(

           "ERROR: Problems with adding new entry" );

        e.printStackTrace();

        return false;

     }

     return true;

  }

    // закрытие соединения с базой данных

  public void destroy()

  {

     try { connect.close();

          }

     catch( Exception e ) {

           System.err.println( "Problem closing the database" );

         }

  }

}

   Исходный html-файл для вызова сервлета DataBaseServlet.java

<!-- DataBaseServlet.shtml -->

<html>

<head>

<meta http-equiv="Content-type" content="text/html; charset=windows-1251">

       <title>Запись информации в базу данных Guests</title>

</head>

<body bgcolor="#FAFAD2">

<h1>Гостевая книга</h1>

<form    action="/databaseservlet" method="post" ><pre>

    Email (*): <input type=text name=Email>

  Фамилия (*): <input type=text name=FirstName>

      Имя (*): <input type=text name=LastName>

 Место работы: <input type=text name=Company>

       Примечание: Заполнение полей (*) обязательно</pre>

 <h3> Какой язык программирования Вы используете?</h3>

 <input type="checkbox" name="C_cpp" value="C_cpp">C++<br>

 <input type="checkbox" name="C_sh" value="C_sh">C#<br>

 <input type="checkbox" name="Java" value="Java">Java<br>

 <input type="checkbox" name="VB6" value="VB6">Visual Basic 6<br><br>

 <input type="submit" value="Послать">

 <input type="reset" value="Очистить">

</form>

</body>

</html>

Контрольное задание 1.11. Составьте собственный вариант приложения DataBaseServle1, включив в число обязательных для заполнения полей формы поле с указанием места работы, и выберите другой фон исходной html-страницы. Протестируйте разработанный проект в среде JBuilder.

1.3. Развертывание Web-приложений на основе сервлетов

Развертывание единственного приложения. После отладки сервлета в той или иной среде программирования необходимо организовать его развертывание (доставку) в некоторый целевой каталог, где сервлет должен работать автономно, вне среды разработки. Выбор целевого каталога осуществляется различными способами в зависимости от среды, в которой проводилась разработка сервлета. Применительно к среде JBuilder в качестве такого каталога наиболее целесообразно выбирать папку ROOT, являющуюся подкаталогом папки webapps сервера Tomcat. В этом случае нет необходимости в переконфигурировании дескриптора развертывания, который хранится в файле web.xml, создаваемом системой JBuilder автоматически. Файл web.xml помещается системой JBuilder в папку defaultroot\WEB_INF проекта и имеет различное содержание для каждого проекта.

Так, для рассмотренного ранее проекта GetServlet файл web.xml имеет следующий вид:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

 <servlet>

   <servlet-name>getservlet</servlet-name>

   <servlet-class>getservlet.GetServlet</servlet-class>

 </servlet>

 <servlet>

   <servlet-name>servlet-shtml</servlet-name>

   <servlet-class>com.borland.jbuilder.webserverglue.shtml.ShtmlLoaderEcho

   </servlet-class>

 </servlet>

 <servlet-mapping>

   <servlet-name>servlet-shtml</servlet-name>

   <url-pattern>*.shtml</url-pattern>

 </servlet-mapping>

 <servlet-mapping>

   <servlet-name>getservlet</servlet-name>

   <url-pattern>/getservlet</url-pattern>

 </servlet-mapping>

</web-app>

Первая строка этого файла представляет собой объявление XML, указывающее на то, что это xml-документ, и содержащее номер версии и тип кодировки. Далее следует комментарий, в котором приводится информация для браузера. Основные данные о проекте содержатся в корневом элементе
web-app с начальным тегом <web-app> и конечным тегом </web-app>, в котором определяется конфигурация сервлета в Web-приложении и путь к сервлету. При этом сервлет GetServlet описывается в корневом элементе при помощи вложенных в него элементов servlet и servlet-mapping.

Элемент servlet имеет структуру

      <servlet>

         <servlet-name>getservlet</servlet-name>

         <servlet-class>getservlet.GetServlet</servlet-class>

      </servlet>

Входящий в эту структуру элемент servlet-name описывает имя пакета
getservlet, которое выбрано при создании сервлета. В этом пакете расположен class-файл сервлета GetServlet.class и путь к нему описывается в элементе servlet-class.

Элемент servlet-mapping, имеет структуру

      <servlet-mapping>

         <servlet-name>getservlet</servlet-name>

         <url-pattern>/getservlet</url-pattern>

      </servlet-mapping>

Входящий в эту структуру элемент servlet-name описывает имя пакета, которое выбрано при создании сервлета. В элементе url-pattern задается шаблон URL-адреса, при помощи которого сервлет запускается для взаимодействия с клиентом.

Процедура развертывания сервлета, созданного в среде JBuilder, в каталог webapps\ROOT сервера Tomcat сводится к следующим шагам.

  1.  Скопировать содержание папки defaultroot проекта на сервер Tomcat в папку webapps\ROOT.
  2.  Перезапустить сервер Tomcat.
  3.  Открыть Microsoft Internet Explorer и вызвать shtml-файл проекта.

Так, например, для разворачивания сервлета GetServlet на сервер Tomcat и запуска этого сервлета при использовании порта 9090 и IP-адреса 127.0.0.1 необходимо выполнить следующие шаги:

  1.  Скопировать папку WEB_INF и html-файл GetServlet.shtml из папки
    defaultroot проекта GetServlet в папку webapps\ROOT сервера Tomcat.
  2.  Перезапустить сервер Tomcat.
  3.  Открыть Microsoft Internet Explorer и ввести в адресную строку адрес http://127.0.0.1:9090/GetServlet.shtml.

Контрольные задания: 

1.12. Развернуть сервлет PostServlet на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1

1.13. Развернуть сервлет ParamServlet на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.14. Развернуть сервлет SelectServlet на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.15. Развернуть сервлет AllParameters на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.16. Развернуть сервлет AllParamList на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.17. Развернуть сервлет AccessInfo на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.18. Развернуть сервлет FileServlet на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.19. Развернуть сервлет SessionServlet на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.20. Развернуть сервлет CookieServlet на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

1.21. Развернуть сервлет DateBaseServlet на сервер Tomcat и запустить этот сервлет через порт 9090 и IP-адрес 127.0.0.1.

Развертывание группы приложений. Рассмотренная методика развертывания (доставки) сервлета позволяет вызывать на клиентскую сторону только тот сервлет, который был развернут на сервер последним. Другие сервлеты, которые были развернуты на сервере ранее, не могут быть вызваны клиентом. Это объясняется тем, что при разворачивании очередного сервлета копируется файл web.xml, созданный средой JBuilder для этого сервлета. При этом вся существовавшая в файле web.xml информация с описанием дескриптора развертывания предыдущего сервлета теряется и развернутый ранее сервлет не может быть отображен клиентом в браузере.

      Поэтому для организации взаимодействия клиента с несколькими сервлетами необходима специальная методика. При этом возможны два пути решения задачи. Первый способ основан на размещении на серверной стороне нескольких серверов Tomcat с различными номерами портов и развертывании на каждом сервере единственного сервлетного приложения согласно изложенной ранее методике. Однако такой способ вряд ли можно считать приемлемым, так как он требует увеличения памяти компьютера, используемого в качестве сервера, и приводит к усложнению адресации при клиент-серверных взаимодействиях. Второй способ основан на построении собственной версии файла web.xml, в которой отображается информация о всех сервлетах, разворачиваемых на единственном сервере Tomcat. Далее приводится возможная методика реализации этого способа.

      Пусть, например, после разворачивания сервлета GetServlet возникает необходимость разворачивания на этом же сервере второго сервлета PostServlet, для которого в среде JBuilder построен файл web.xml, имеющий следующий вид:

Файл web.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

 <servlet>

   <servlet-name>postservlet</servlet-name>

   <servlet-class>postservlet.PostServlet</servlet-class>

 </servlet>

 <servlet>

   <servlet-name>servlet-shtml</servlet-name>

   <servlet-class>com.borland.jbuilder.webserverglue.shtml.ShtmlLoaderEcho

   </servlet-class>

 </servlet>

 <servlet-mapping>

   <servlet-name>servlet-shtml</servlet-name>

   <url-pattern>*.shtml</url-pattern>

 </servlet-mapping>

 <servlet-mapping>

   <servlet-name>postservlet</servlet-name>

   <url-pattern>/postservlet</url-pattern>

 </servlet-mapping>

</web-app>

      Информация о сервлете PostServlet содержится в этом файле в элементе servlet, где описывается путь к class-файлу PostServlet.class

      <servlet>

         <servlet-name>postservlet</servlet-name>

         <servlet-class>postservlet.PostServlet</servlet-class>

      </servlet>

      Кроме того, в элементе servlet-mapping описывается шаблон URL-адреса, при помощи которого сервлет вызывается в браузер:

      <servlet-mapping>

        <servlet-name>postservlet</servlet-name>

        <url-pattern>/postservlet</url-pattern>

      </servlet-mapping>

      Для построения объединенного xml-файла следует включить эти элементы в ранее созданный для сервлета GetServlet файл web.xml. В результате получим объединенный файл web.xml, в котором содержатся элементы для развертывания сервлета GetServlet и сервлета PostServlet.

Объединенный файл web.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

 <servlet>

   <servlet-name>postservlet</servlet-name>

   <servlet-class>postservlet.PostServlet</servlet-class>

 </servlet>

 <servlet>

   <servlet-name>getservlet</servlet-name>

   <servlet-class>getservlet.GetServlet</servlet-class>

 </servlet>

 <servlet>

   <servlet-name>servlet-shtml</servlet-name>

   <servlet-class>com.borland.jbuilder.webserverglue.shtml.ShtmlLoaderEcho

   </servlet-class>

 </servlet>

 <servlet-mapping>

   <servlet-name>servlet-shtml</servlet-name>

   <url-pattern>*.shtml</url-pattern>

 </servlet-mapping>

 <servlet-mapping>

   <servlet-name>postservlet</servlet-name>

   <url-pattern>/postservlet</url-pattern>

 </servlet-mapping>

 <servlet-mapping>

   <servlet-name>getservlet</servlet-name>

   <url-pattern>/getservlet</url-pattern>

 </servlet-mapping>

</web-app>

      Именно этот файл и следует поместить в папку webapps\ROOT\WEB_INF сервера Tomcat вместо существующего там файла web.xml. Для окончательного развертывания дополнительного сервлета PostServlet следует скопировать файл PostServlet.shtml из папки defaultroot этого сервлета в папку
w
ebapps\ROOT сервера Tomcat.

      Развертывание на одном сервере произвольного числа сервлетов осуществляется аналогично. Необходимо только иметь в виду, что первый сервлет следует разворачивать согласно методике «Развертывание единственного приложения», а все остальные сервлеты – согласно методике «Развертывание группы приложений». При этом во избежание случайного удаления создаваемого объединенного xml-файла полезно сохранить для него резервную копию.

Контрольные задания: 

1.22. Развернуть построенные в среде JBuilder сервлеты GetServlet и PostServlet на сервер Tomcat и запустить каждый сервлет через порт 9090 и IP-адрес 127.0.0.1

1.23. Развернуть на сервере Tomcat помимо развернутых в задании 1.22 сервлетов также сервлет ParamServlet и запустить его через порт 9090 и
IP-адрес 127.0.0.1

1.24. Развернуть на сервере Tomcat помимо развернутых в задании 1.23 сервлетов также сервлет SelectServlet и запустить его через порт 9090 и IP-адрес 127.0.0.1

1.25. Развернуть на сервере Tomcat помимо развернутых в задании 1.24 сервлетов также сервлет AllParameters и запустить его через порт 9090 и IP-адрес 127.0.0.1

1.26. Развернуть на сервере Tomcat помимо развернутых в задании 1.25 сервлетов также сервлет AccessInfo и запустить его через порт 9090 и IP-адрес 127.0.0.1

Выводы

Сервлеты выполняются на Web-сервере, действуя в качестве посредника между http-запросом, поступающим от Web-браузера клиента, и приложениями или базами данных на сервере. Использование сервлетов является весьма эффективным средством для организации клиент-серверных взаимодействий, поскольку при повторных http-запросах не требуется создавать новый процесс, как это имеет место при использовании технологии CGI. После отладки и тестирования сервлета в используемой среде программирования необходимо организовать его развертывание (доставку) в некоторый целевой каталог сервера Tomcat, где сервлет должен работать автономно, вне среды разработки.