Обучение Java. Сервлеты

Примеры URL сервлетов в HTML тегах

Страница, возвращаемая сервлетом ShowCartServlet, имеет несколько ссылок, каждая из которых имеет ссылку на сервлет. Вот код, который показывает одну из этих ссылок:
public class ShowCartServlet extends HttpServlet {
public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... out.println(... + "Check Out      " + ...); ... } ... }
Этот код позволяет вывести HTML страницу со следующим кодом: 
" + ... "" + ... "" + ... "" + ...); out.close(); } ... }
Код генерирует HTML страницу с тегом:

Вы увидите эту ссылку, если просмотрите код страницы загруженный сервлетом cashier. Отправьте форму. Сервлет receipt
вернет Вам страницу, которая содержит следующий пример. Страница, загруженная сервлетом receipt, перегружает сама себя так, что если хотите посмотреть HTML код, делайте это быстро!.

Страница, возвращаемая сервлетом receipt, содержит мета тег, который использует URL сервлета в качестве значения атрибута http-equiv. Вообще говоря, тег перенаправляет на главную страницу магазина Duke's Bookstore
после того, как отблагодарит пользователя за помещенный заказ. Ниже приведен код для вывода данного тега:
public class ReceiptServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... out.println("" + " Receipt " + "" + "" + ... } ... }
Этот код генерирует HTML страницу со следующим тегом:  


Выполнение сервлетов

Этот урок покажет Вам несколько путей выполнения сервлетов: 

Вызов сервлета из адресной строки броузера

Сервлет могно вызвать напрямую, напечатав URL в адресной строке броузера. Это так, как Вы заходите на стартовую страницу в примере магазина Duke's Bookstore. В этом разделе будет показан основной вид URL для сервлета.

Вызов сервлета из HTML страницы

Чтобы вызвать сервлет с помощью броузера из HTML страницы, поместите URL сервлета в соответствующий HTML тег. (В этом разделе необходимы знания языка HTMLВызов сервлета из HTML страницы.) Теги, в которые можно помещать URL включают те, что начинаются с " В этом разделе будут обсуждаться сервлеты ShowCart, Cashier, и Receipt из примера магазина Duke's Bookstore. По счастливой случайности, в порядке, как будут рассматриваться примеры, сервлеты отображают страницы, когда Вы просматриваете Вашу корзину и покупаете книги.
Для более быстрого доступа к сервлету ShowCart, нажмите ссылку Show Cart
на главной странице магазина Duke's Bookstore. Если Вы используете servletrunner или сервер для запуска примера, перейдите на главную страницу магазина используя советы . Но ради интереса, Вы можете добавить книгу в Вашу корзину, прежде чем получите доступ к сервлету ShowCart.

URL сервлета может быть использован в HTML тегах, так же как URL для CGI-скрипта или URL файла. В этой части обсуждается, как использовать URL сервлета, в случае ссылки, запроса из формы, и как использовать META теги для обновления страницы. Для данной части необходимы знания языка HTML. Если Вы не знакомы с HTML, Вы можете узнать о нем из множества книг или заглянув HTML 3.2 Reference SpecificationВызов сервлета из HTML страницы.
 
Для урока необходимо: 
  • Компьютер, localhost, с запущенным JSDK сервером (JSDK 2.1) или servletrunner (JSDK 2.0) или сервлет-совместимый веб сервер, такой как Java Web ServerВызов сервлета из HTML страницы на порту 8080 

  • Пример, Duke's Bookstore, размещенный в корневой директории для сервлетов. Для сервера из пакета JSDK 2.1 означает, что классы должны быть размещены в поддиректории WEB-INF корневого каталога сервера. Для утилиты servletrunner из пакета JSDK 2.0, что классы находятся в директории сервлета указанной в -d опции.  

  • Если Вы соблюдаете два данных положения, значит, Вы сможете запустить пример магазина с помощью указанного в примере URL.

    Вызов сервлетов из адресной строки броузера

    URL для сервлета имеет следующий вид, где имя-сервлета
    относится к имени, которое Вы присвоили сервлету: 
    http://имя-хоста:port/servlet/имя-сервлета
    Например, Сервлет, который открывает главную страницу примера Duke's Bookstore имеет свойство servlet.bookstore.code=BookStoreServlet. Чтобы увидеть начальную страницу, например, напечатайте следующий URL в адресной строке Вашего броузера:
    http://localhost:8080/servlet/bookstore
    URL сервлета может включать запросы, такие как HTTP запросы GET. Например, сервлет, который выводит информацию по конкретной книге, использует складской номер книги для поиска. Имя сервлета - bookdetails; тогда URL для этого сервлета, чтобы получить (GET) и вывести информацию по заданной книге, будет выглядеть так:
    http://localhost:8080/servlet/bookdetails?bookId=203

    Данные HTTP заголовка

    Вам необходимо установить данные HTTP заголовка, прежде чем вы получите доступ к объектам Writer или OutputStream. Класс HttpServletResponse предоставляет методы для доступа к данным заголовка. Например, метод setContentType устанавливает тип содержимого (Content-type). (Этот заголовок чаще всего единственный устанавливаемый вручную.)

    Interface javax.servlet.SingleThreadModel

    public interface SingleThreadModel
    Defines a "single" thread model for servlet execution. This empty interface allows servlet implementers to specify how the system should handle concurrent calls to the same servlet.
    If the target servlet is flagged with this interface, the servlet programmer is guaranteed that no two threads will execute concurrently the service method of that servlet. This guarantee is ensured by maintaining a pool of servlet instances for each such servlet, and dispatching each service call to a free servlet.
    In essence, if the servlet implements this interface, the servlet will be thread safe. Note that this will not prevent synchronization problems associated with accessing shared resources (such as static class variables or classes outside the scope of the servlet).

    Объекты HttpServletRequest

    Объекты HttpServletRequest предоставляют доступ к данным HTTP заголовка, таким как любые закладки (cookies) найденные в запросе и HTTP методы, с помощью которых был сделан запрос. Объект HttpServletRequest также позволяет Вам получить аргументы, которые клиент направил вместе с запросом.
    Чтобы получить данные клиента:
  • Метод getParameter возвращает величину именованных параметров. Если Ваш параметр может иметь более чем одну величину, используйте getParameterValues. Метод getParameterValues возвращает массив величин именованного параметра. (Метод getParameterNames предоставляет имена параметров.) 

  • Для HTTP запросов GET, метод getQueryString возвращает строковую (String) величину необработанных данных клиента. Вам самим необходимо разобрать строку, чтобы получить параметры и значения. 

  • Для HTTP запросов POST, PUT, и DELETE,
  •  
  • Если вы ожидаете текстовую информацию, метод getReader возвращает объект BufferedReader, чтобы Вы могли использовать, считать необработанные данные. 

  • Если Вы ожидаете двоичные данные, метод getInputStream возвращает объекта ServletInputStream, чтобы Вы могли использовать, считать необработанные данные. 

  • Замечание:
    Используйте либо метод getParameter[Values] либо один из других методов для собственного разбора данных. Они не могут быть использованы вместе в одном запросе.
     

    Объекты HttpServletResponse

    Объект HttpServletResponse предоставляет два пути возвращения данных к пользователю: 
  • Метод getWriter возвращает объект Writer  

  • Метод getOutputStream возвращает поток ServletOutputStream

     

  • Используйте метод getWriter для возвращения пользователю текстовой информации, и метод getOutputStream для двоичных данных.
    Закрытие объектов Writer или ServletOutputStream после отправки ответа позволяет серверу узнать, когда завершился ответ.
     

    Обработка GET и POST запросов

    Методы, которым метод service передает управление HTTP запросов, включают:
  • doGet, для обработки GET, условный GET, и HEAD запросов.  

  • doPost, для обработки POST запросов  

  • doPut, для обработке PUT запросов

  • doDelete, для обработки DELETE запросов  

  • По умолчанию, эти методы возвращают BAD_REQUEST (400) error (ошибка 400). Ваш сервлет должен переопределить метод или методы, разработанные для обработки HTTP взаимодействий, которые поддерживают их. В этой части показано, как выполнять методы которые поддерживают самые основные HTTP запросы: GET и POST.
    Метод service также вызывает метод doOptions, когда сервлет получает запрос OPTIONS (ОПЦИИ), и метод doTrace, когда сервлет получает запрос TRACE. По умолчанию метод doOptions автоматически определяет, какие опции HTTP поддерживаются, и возвращает эту информацию. По умолчанию метод doTrace объединяет ответ с сообщением, содержащим все заголовки, отправленные в запросе трассировки. Эти методы обычно не переопределяются.
     

    Описание сервлета

    Вдобавок к обработке клиентских HTTP запросов, сервлеты также вынуждены поддерживать описание самих себя. Этой часть покажет вам получать описание, переопределяя метод getServletInfo, который поддерживает описание сервлета.

    Получение описания сервлета

    Некоторые приложения, такие как Java Web Server Administration ToolПолучение описания сервлета, получают наглядную информацию от сервлета и выводят ее. Описание сервлета это строка, которая описывает назначение сервлета, его автора, его номер его версии, и все, что автор сервлета посчитал важным указать.
    Метод, который возвращает эту информацию суть метод getServletInfo, который по умолчанию возвращает null. Вам необязательно переопределять этот метод, но приложения не смогут предоставлять информацию о сервлете, пока Вы это не сделаете.
    Следующий пример демонстрирует описание сервлета BookStoreServlet:  
    public class BookStoreServlet extends HttpServlet { ... public String getServletInfo() { return "The BookStore servlet returns the " + "main web page for Duke's Bookstore."; } }

    Потоковый вывод

    Сервлеты HTTP, как правило, поддерживают обработку нескольких клиентов одновременно. Если методы в Вашем сервлете, работающие на клиента, используют общие ресурсы, то вы должны либо:
  • Синхронизировать доступ к этому ресурсу, либо 

  • Создать сервлет, который обслуживает только одного клиента в определенный момент времени. 

  • Этот урок расскажет вам, как выполнить второй вариант. (Первый обсуждается в уроке о потоках.)
     

    Сервлеты HTTP, как правило, поддерживают обработку нескольких клиентов одновременно. Если методы в вашем сервлете, работаюшие на клиента, используют общие ресурсы, то Вы должны, согласовать управление, создав сервлет, который обслуживает только одного клиента в определенный момент времени. (Вы также можете синхронизировать доступ к этому ресурсу. Эта тема обсуждается в уроке о потоках)
    Чтобы сервлет обслуживал только одного клиента в определенный момент времени, Вам надо реализовать интерфейс SingleThreadModelПотоковый вывод в добавление к наследованию класса HttpServlet.
    Реализация интерфейса SingleThreadModel не подразумевает под собой написание каких-либо дополнительных методов. Вы просто реализуете этот интерфейс, и сервер обеспечит сервлету выполнение только одного service в определенный момент времени.
    Например, сервлет ReceiptServlet принимает данные об имени пользователя, номере кредитной карточки и благодарит его за помещенный заказ. Если этот сервлет обновил базу данных, например, ту, что содержит информацию инвентаризации, тогда связь с базой данных является разделяемым ресурсом. Сервлет мог бы одинаково синхронизировать доступ к этому ресурсу, или реализовать интерфейс SingleThreadModel. Если сервлет реализует данный интерфейс, единственное изменение в коде по сравнению с выделено жирным шрифтом:
    public class ReceiptServlet extends HttpServlet implements SingleThreadModel {
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... } ... }

    Управление запросами GET и POST

    Чтобы управлять HTTP запросами из сервлета, Наследуйте класс HttpServlet и переопределите методы сервлета, которые управляют HTTP запросами, поддерживаемые Вашим сервлетом. Этот урок демонстрирует управление запросами GET и POST. Методами, управляющими этими запросами, являются методы doGet и doPost.
     

    Управление запросами GET

    Управление запросами GET влечет за собой переопределения метода doGet. Следующий пример показывает, как сервлет BookDetailServlet делает это. Методы, описанные в разделе , выделены жирным шрифтом
    public class BookDetailServlet extends HttpServlet {
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... // устанавливает заголовок "content-type" // прежде сем получить доступ к Writer
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    // затем пишем ответ
    out.println("" + " Book Description" + ...);
    //берем идентификатор требуемой книги
    String bookId = request.getParameter("bookId");
    if (bookId != null) { // печатаем информацию о книге
    ... } out.println(""); out.close();
    } ... }
    Этот сервлет наследует класс HttpServlet и переопределяет метод doGet.
    Внутри метода doGet, метод getParameter берет предполагаемый аргумент.
    Для ответа, пример метода doGet использует объект Writer, полученный из объекта HttpServletResponse, чтобы вернуть клиенту текстовую информацию. Прежде чем получить объект writer, в примере устанавливается заголовок content-type. И в конце метода doGet, после отправки ответа, объект Writer закрывается.
     

    Управление запросами POST

    Управление запросами POST влечет за собой переопределения метода doPost. Следующий пример показывает, как сервлет ReceiptServlet делает это. Методы, описанные в разделе , выделены жирным шрифтом
    public class ReceiptServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... // устанавливает заголовок "content-type" // прежде сем получить доступ к Writer
    response.setContentType("text/html"); PrintWriter out = response.getWriter();
    // затем пишем ответ
    out.println("" + " Receipt " + ...);
    out.println("

    Thank you for purchasing your books from us " + request.getParameter("cardname") + ...); out.close(); } ... }
    Этот сервлет наследует класс HttpServlet и переопределяет метод doPost.
    Внутри метода doPost метод getParameter берет предполагаемый аргумент.
    Для ответа, пример метода doPost использует объект Writer, полученный из объекта HttpServletResponse, чтобы вернуть клиенту текстовую информацию. Прежде чем получить объект Writer, в примере устанавливается заголовок content-type. И в конце метода doPost, после отправки ответа, объект Writer закрывается.

    Взаимодействия с клиентами

    HTTP сервлет поддерживает запросы клиента через метод service. Метод service поддерживает стандартные HTTP запросы клиента, отправляя каждый запрос соответствующему разработанному для обработки данного запроса методу. Например, метод service вызывает метод doGet показанный ранее в simple example servlet.
     

    Запросы и Ответы

    В этой части обсуждаются объекты, которые представляют клиентский запрос (HttpServletRequest object) и сервлетный ответ (HttpServletResponse object). Эти объекты используются методом service и методами, которые вызывают метод service для обработки HTTP запросов.
     

    Методы класса HttpServlet управляющие запросами клиента используют два аргумента:
  • Объект HttpServletRequest, который возвращает данные от
    клиента. 

  • Объект HttpServletResponse, который возвращает ответ к
    клиенту.

  •  

    Использование закладок

    Закладки (Cookies) это способ сервера (или сервлета, как части сервера) посылать клиенту на хранение часть информации, чтобы потом получать эту информацию от клиента. Сервлеты посылают закладки клиенту, добавляя код в ответе в HTTP заголовки. Клиенты автоматически возвращают закладки, добавляя код в запросы в HTTP заголовках.
    Каждый заголовок HTTP запроса и ответа именован и имеет единственное значение. Например, закладкой мог бы быть заголовок с именем BookToBuy со значением 304qty1, сообщающим вызываемому приложению, что пользователь хочет купить книгу с номером 304 количеством 1 единица. (Закладки и их значения зависят от приложений.)
    Множественные закладки могут иметь одно и тоже имя. Например, сервлет может послать две закладки, имя которых BookToBuy; одна может иметь величину приведенную выше, 304qty1, когда вторая - значение 301qty3. Эти закладки будут означать, что пользователь хочет купить одну книгу с номером 304, и три книги с номером 301.
    В добавление к имени и значению, Вы также можете предоставить необязательные элементы, такие, как комментарии. Текущий броузер может не всегда правильно воспринимать необязательные параметры, поэтому Вы не должны полагаться на них.
    Сервер может обеспечить одну или более закладок для клиента. Предполагается, что программа клиента, как web броузер, должна поддерживать 20 закладок на хост, как минимум четыре килобайта каждая.
    Когда Вы посылаете закладку клиенту, стандартный кэш HTTP/1.0 не будет кэшировать страницу. На данный момент, javax.servlet.http.Cookie не поддерживает HTTP/1.1 модули кэширования.
    Закладки, которые клиент сохранил для сервера, возвращаются клиентом только этому серверу. Сервер может включать множество сервлетов; пример Duke's Bookstore
    сделан из нескольких сервлетов работающих на одном сервере. Потому как закладки возвращаются серверу, сервлеты работающие на этом сервере совместно используют эти закладки. Пример в этом разделе иллюстрирует этот факт на сервлетах CatalogServlet и ShowCart, работающих с одними закладками.

    Заметка:  В этом разделе приводится пример не являющийся частью примера Duke's Bookstore. Пример Duke's Bookstore мог бы использовать код использованный в этом уроке, если бы использовал закладки вместо прослеживания сессии для определения заказа клиента. Поскольку закладки не являются частью примера Duke's Bookstore, будем считать этот код псевдокодом

    Чтобы отправить закладку, 

  • объект CookieИспользование закладок


  •  


  •  


  • Чтобы извлечь информацию из закладки, 

  • из пользовательского запроса


  • Найдите закладку или закладки с именем, которое Вас интересует, используя стандартные программные операции 


  • , которые были найдены


  •  

    Отправка закладки

    Закладки отправляются как заголовки ответа клиенту; они добавляются с помощью метода addCookie класса HttpServletResponse. если Вы используете Writer для отправки закладки пользователю, Вы должны использовать метод addCookie, прежде чем вызвать метод getWriter класса HttpServletResponse.
    Продолжая пример CatalogServlet, приводим следующий код для отправки закладок:
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... //Если пользователь хочет добавить книгу, запоминаем это добавляя закладку
    if (values != null) { bookId = values[0]; Cookie getBook = new Cookie("Buy", bookId); getBook.setComment("User has indicated a desire " + "to buy this book from the bookstore."); response.addCookie(getBook);
    } ... }

    Отслеживание сессии

    Отслеживание сессии это механизм, который сервлеты используют, чтобы поддерживать статус между сериями запросов от одного и того же пользователя (запросов произведенных из одного окна броузера) в течение определенного промежутка времени.
    Сессии используются разными сервлетами для доступа к одному клиенту. Это удобно для приложений построенных на нескольких сервлетах. Например, Duke's Bookstore
    использует отслеживание сессии для того, чтобы сохранять книги, выбранные клиентом. Все сервлеты в примере имеют доступ к пользовательской сессии.
    Чтобы использовать отслеживание сессии,
  • Создайте для пользователя сессию (объект HttpSessionОтслеживание сессии). 

  • Сохраняйте или читайте данные из объекта HttpSession.

  • Уничтожьте сессию (необязательное).

  •  

    Отслеживания сессии

    Отслеживание сессии это механизм, который сервлеты используют, чтобы поддерживать статус между сериями запросов от одного и того же пользователя (запросов произведенных из одного окна броузера) в течение определенного промежутка времени.
     

    Получение сессии

    Метод getSession объекта HttpServletRequest возвращает сессию пользователя. Когда Вы вызываете этот метод с аргументом create равным true, среда выполнения создает при необходимости сессию.
    Чтобы правильно организовать сессию, Вам надо вызвать метод getSession прежде чем будет запущен выходной поток ответа. (Если Ваш ответ использует Writer, Вам надо вызвать метод getSession, прежде чем Вы получите доступ к Writer, прежде отправки данных ответа.)
    Пример Duke's Bookstore использует прослеживание сессии для того, чтобы хранить информацию о книгах в корзине для покупок пользователя. Вот пример сервлета CatalogServlet устанавливающего сессию пользователя:
    public class CatalogServlet extends HttpServlet {
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Получаем сесию пользователя и корзину для покупок
    HttpSession session = request.getSession(true);
    ... out = response.getWriter(); ... } }

    Получение значения закладки

    Чтобы получить значение закладки, используйте ее метод getValue. Продолжая пример сервлета ShowCartServlet:
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... //Управление удалением из корзины
    String bookId = request.getParameter("Remove"); ... if (bookId != null) { //Находим закладку соответствующую данной книге
    Cookie[] cookies = request.getCookies(); for(i=0; i cookies.length; i++) { Cookie thisCookie=cookie[i]; if (thisCookie.getName().equals("Buy") { thisCookie.getValue().equals(bookId); i++) } //Удаляем закладку устанавливая ее возраст равным нулю
    thisCookie.setMaxAge(0); } } }
    //прежде чем начать вывод, устанавливаем тип содержимого
    response.setContentType("text/html"); PrintWriter out = response.getWriter();
    //Выводим ответ
    out.println(" " + "Your Shopping Cart" + ...); ... }

    Сохранение и получение данных сессии

    Интерфейс HttpSession предоставляет методы, которые сохраняют и возвращают данные:
  • Стандартные свойства сессии, такие как идентификатор сессии. 

  • Данные приложения, которые сохраняются в виде пары с именным ключом, когда имя это строка (String) и величина - объект Java. (Также как java.util.Dictionary.) Поскольку используется доступ нескольких сервлетов к пользовательской сессии, Вам надо выбрать условное именование для организации имен соответствующих пользовательским данным. Это позволит сервлетам избежать случайной перезаписи одних величин другими. Одина из таких условностей servletname.name, где servletname это полное имя сервлета, включая его пакет. Например, com.acme.WidgetServlet.state это закладка с именем сервлета com.acme.WidgetServlet и именем state.

  • Пример Duke's Bookstore использует прослеживание сессии для того, чтобы хранить информацию о книгах в корзине для покупок пользователя. Вот пример сервлета CatalogServlet получающего идентификатор пользовательской сессии, который получает и устанавливает данные, соответствующие сессии этого пользователя:
    public class CatalogServlet extends HttpServlet {
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Получаем сесию пользователя и корзину для покупок
    HttpSession session = request.getSession(true); ShoppingCart cart = (ShoppingCart)session.getValue(session.getId());
    // Если у пользователя нет корзины, создаем ее
    if (cart == null) { cart = new ShoppingCart(); session.putValue(session.getId(), cart);
    } ... } }
    Потому как объект может быть ассоциирован с сессией, пример Duke's Bookstore
    хранит книги отобранные пользователем в объекте. Этот объект типа ShoppingCart и каждая книга, отобранная пользователем, хранится в корзине для покупок, то есть в объекте ShoppingCartItem. Например, вот, что получается в таком случае в методе doGet сервлета CatalogServlet:
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    HttpSession session = request.getSession(true); ShoppingCart cart = (ShoppingCart)session.getValue(session.getId()); ... // Смотрим есть ли покупки в корзине

    String bookId = request.getParameter("Buy");

    // Если пользователь хочет добавить книгу, добавляем и пишем ответ

    String bookToAdd = request.getParameter("Buy"); if (bookToAdd != null) { BookDetails book = database.getBookDetails(bookToAdd);

    cart.add(bookToAdd, book);

    out.println("

    " + ...); } }

    В заключении, отметим, что сессия может быть разработана как новая. Новая сессия - если метод isNew класса HttpSession возвращает true, показывает, например, что, клиент не устанавливал сессию еще. С новой сессий данные еще не ассоциированы.

    Вам надо разобраться с ситуациями вызывающими новые сессии. В примере Duke's Bookstore

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

     

    Создание закладки

    Конструктор класса javax.servlet.http.Cookie создает закладу с начальным именем и значением. Вы можете изменить значение закладки позже, вызвав метод setValue.
    Имя закладки должно быть HTTP/1.1 токен. Токены это строки, не содержащие специальных символов перечисленных в документе RFC 2068Создание закладки. (буквенно-численные строки квалифицируемые как токены.) В добавление, имена, начинающиеся со знака доллар ("$") зарезервированы документом RFC 2109Создание закладки.
    Значением строки может быть любая строка, хотя не гарантируется, что значение null, будет одинаково работать на всех броузерах. В добавление, если Вы отправляете закладку, которая подчиняется оригинальной спецификации закладок Netscape's, не используйте пробелы или ниже приведенные символы:
    [ ] ( ) = , " / ? @ : ;
    Если сервлет возвращает ответ пользователю, используя Writer, создавайте закладку, прежде чем обратитесь к Writer. (Поскольку закладки отправляются к клиенту как заголовок, заголовки должны быть прописаны, прежде чем произойдет обращение к Writer.)
    Если бы сервлет CatalogServlet использовал закладки для того, чтобы проследить заказ клиента, он бы создавал бы их следующим образом:
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Смотрим есть ли покупки в корзине
    String bookId = request.getParameter("Buy");
    //Если пользователь хочет добавить книгу, запоминаем это добавляя закладку
    if (bookId != null) { Cookie getBook = new Cookie("Buy", bookId);
    ... }
    // прежде чем начать вывод, устанавливаем тип содержимого
    response.setContentType("text/html");
    // теперь выводим данные ответа
    PrintWriter out = response.getWriter(); out.println("" + " Book Catalog " + ...); ... }

    Управление всеми броузерами

    По умолчанию, прослеживание сессии использует закладки, чтобы ассоциировать идентификатор сессии с пользователем. Чтобы также поддерживать пользователей, у которых броузер не работает с закладками, или включен в режим игнорирования их, Вы должны использовать перезапись URL. (По скольку некоторые сервера поддерживают перезапись URL, утилита servletrunner являющаяся частью JSDK2.0 не поддерживает это. Для того чтобы прослеживания сессии работало, когда сервлет запущен с помощью servletrunner, клиент должен поддерживать закладки.)
    Когда Вы используете перезапись URL, Вы вызываете методы, когда необходимо, так, чтобы идентификатор был включен в ссылку. Вы должны использовать эти методы для каждой ссылке в ответе сервлета.
    Методом, который ассоциирует идентификатор сессии с URL, является метод HttpServletResponse.encodeUrl в пакете JSDK2.0 и HttpServletResponse.encodeURL в пакете JSDK2.1. Если Вы переадресовываете пользователя на другую страницу, методом, который ассоциирует идентификатор сессии с URL, является метод HttpServletResponse.encodeRedirectUrl в пакете JSDK2.0 и HttpServletResponse.encodeRedirectURL в пакете JSDK2.1.
    Методы URL кодирования и кодирования переадресации определяют должен ли URL быть перезаписан и возвращают измененный или не измененный URL. (Правила для URL-ов и переадресуемых URL-ов разные, но в основном, если сервер определяет, что данный броузер поддерживает закладки, URL переписан не будет.)
    Замечание: Здесь показан код, не являющийся частью примера Duke's Bookstore для JSDK2.1. Пример Duke's Bookstore мог бы содержать код, подобный приведенному ниже, в случае если бы использовалась перезапись URL. Поскольку перезапись URL не является частью примера Duke's Bookstore, будем считать этот код псевдокодом.
    Если бы пример Duke's Bookstore использовал перезапись URL, его код в сервлете CatalogServlet мог бы выглядеть следующим образом:
    public class CatalogServlet extends HttpServlet {
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Получаем сесию пользователя, корзину для покупок, Writer и тому подобное.

    ... // пишем ответ

    out.println("" + ...); ... // берем каталог и отправляем его, красиво отформатировав

    BookDetails[] books = database.getBooksSortedByTitle(); ... for(int i=0; i < numBooks; i++) { ... //Выводим инвормацию для книги в две строчки

    out.println("" + ...

    "
    response.encodeURL("/servlet/bookdetails?bookId=" + bookId) + "\"> " + books[i].getTitle() + "  " + ...

    "response.encodeURL("/servlet/catalog?Buy=" + bookId) + "\">   Add to Cart  " +

    } } }

    Отметим, что сервлет CatalogServlet возвращает пользователю две ссылки для каждой книги. Одна ссылка предлагает просмотр подробностей касающихся книги, и вторая позволяет добавить книгу в корзину для покупок. Обе ссылки будут переписаны так как, опять, каждая ссылка, которую сервлет возвращает пользователю должна быть переписана, когда Вы используете метод перезаписи URL.

    Когда пользователь жмет на ссылку переписанного URL, сервлет определяет и извлекает идентификатор сессии. Далее используется метод getSession, чтобы получить соответствующий идентификатору сессии объект HttpSession.

    И обратно, если броузер пользователя не поддерживает закладки, и пользователь нажимает на не переписанный URL, сессия пользователя пропадает. Сервлет, взаимодействуя через эту ссылку, создает новую сессию, а новая сессия не содержит данных соответствующих прежней сессии. Если сервлет теряет данные сессии, эти данные теряются для всех сервлетов их использующих. Вы должны также использовать методы перезаписи URL, если хотите, чтобы Ваш сервлет поддерживал клиентов, не работающих или не поддерживающих закладки.

    Сохранение статуса клиента

    Интерфейс сервлета позволяет проследить статус клиента:

    Установка атрибутов закладки

    Класс Cookie обеспечивает набор методов для установки параметров закладки и ее атрибутов. Использование этих методов поступательно; они описаны в документации для класса Cookie.
    Следующий пример показывает, как установить комментарий для закладки CatalogServlet. Комментарий описывает назначение закладки.
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... //Если пользователь хочет добавить книгу, запоминаем это добавляя закладку
    if (values != null) { bookId = values[0]; Cookie getBook = new Cookie("Buy", bookId); getBook.setComment("User wants to buy this book " + "from the bookstore.");
    } ... }
    Вы также можете установить максимальный возраст закладки. Этот атрибут полезен, например, для удаления закладки. И опять, если бы Duke's Bookstore
    использовал закладки для того, чтобы проследить заказ клиента, то, например, использовал бы данный атрибут для удаления книги из заказа пользователя. Пользователь удаляет книгу из корзины для покупок в сервлете ShowCartServlet; код бы мог выглядеть следующим образом:
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... // Управление удалением из корзины
    String bookId = request.getParameter("Remove"); ... if (bookId != null) { // находим закладку которая отвечает за удаляемую книгу
    ... // Удаляем закладку устанавливая ее возраст равным нулю
    thisCookie.setMaxAge(0);
    ... }
    // прежде чем начать вывод, устанавливаем тип содержимого
    response.setContentType("text/html"); PrintWriter out = response.getWriter();
    //Выводим ответ
    out.println(" " + "Your Shopping Cart" + ...); ... }

    Закладки

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

    Запрашивание закладок

    Клиенты возвращают закладки как поля, добавленные в HTTP заголовок запроса. Чтобы запросить какую-либо закладку, Вам надо запросить все закладки, используя метод getCookies из класса HttpServletRequest.
    Метод getCookies возвращает массив объектов Cookie, который Вы можете просмотреть, чтобы найти необходимую вам закладку или закладки. (Запомните, что множественные закладки имеют одно и тоже имя. Чтобы получить имя закладки используйте ее метод getName.)
    Продолжая пример сервлета ShowCartServlet:
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ...
    //Управление удалением из корзины
    String bookId = request.getParameter("Remove"); ... if (bookId != null) {
    //находим закладку которая отвечает за удаляемую книгу
    Cookie[] cookies = request.getCookies();
    ...
    //Удаляем закладку устанавливая ее возраст равным нулю
    thisCookie.setMaxAge(0);
    }
    //прежде чем начать вывод, устанавливаем тип содержимого
    response.setContentType("text/html"); PrintWriter out = response.getWriter();
    //Выводим ответ
    out.println(" " + "Your Shopping Cart" + ...); ... }

    Завершение сессии

    Сессия пользователя может быть завершена вручную или, в зависимости от того, где запущен сервлет, автоматически. (Например, Java Web Server автоматически завершает сессию, когда в течение определенного времени не происходит запросов, по умолчанию 30 минут.) Завершить сессию означает удаление объекта HttpSession и его величин из системы.
    Чтобы вручную завершить сессию, используйте метод сессии invalidate. У некоторых программ уже есть такие точки, в которых происходит завершение сессии. Пример Duke's Bookstore
    завершает сессию пользователя после того, как он осуществил покупку книг. Это происходит в сервлете ReceiptServlet:
    public class ReceiptServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ... scart = (ShoppingCart)session.getValue(session.getId()); ... // Очищаем корзину завершая сессию
    session.invalidate();
    // прежде чем начать вывод, устанавливаем тип содержимого
    response.setContentType("text/html"); out = response.getWriter(); ... } }

    Договоренности именования атрибутов

    Все сервлеты в контексте совместно используют атрибуты, находящиеся в интерфейсе ServletContext. Чтобы избежать столкновений имен атрибутов, имена их используют те же правила что и имена пакетов. Например, сервлеты магазина Duke's Bookstore
    совместно используют атрибут examples.bookstore.database.BookDBFrontEnd. Имена, начинающиеся с префиксов java.*, javax.*, и sun.* зарезервированы.

    Обучение Java. Сервлеты

    Получение значения атрибута также просто как вызов метода ServletContext.getAttribute. Следующий пример демонстрирует, как сервлет CatalogServlet получает значение атрибута во время инициализации:
    public class CatalogServlet extends HttpServlet {
    public void init() throws ServletException { BookDBFrontEnd bookDBFrontEnd = (BookDBFrontEnd)getServletContext().getAttribute( "examples.bookstore.database.BookDBFrontEnd");
    if (bookDBFrontEnd == null) { getServletContext().setAttribute( "examples.bookstore.database.BookDBFrontEnd", BookDBFrontEnd.instance()); } } ... }

    Использование других ресурсов сервера (JSDK 2.1)

    Чтобы Ваш сервлет получил доступ к другим ресурсам сервера, таким как другой сервлет, страница JSP, или CGI скрипт, Вы можете:
  • Либо дать сервлету сделать HTTP запрос. (Это относится к общему программированию на Java. Для более подробной информации, обратитесь к ресурсу Working with URLsИспользование других ресурсов сервера (JSDK 2.1).) 

  • Либо сделать запрос ресурса с помощью объекта RequestDispatcher, если ресурс доступен на сервере, на котором запущен сервлет.

  • Этот урок обсуждает второй из вышеуказанных пунктов:
  • для ресурса.

  • к ресурсу так, чтобы он отвечал запросу клиента.

  • в выходной поток сервлета.


  • Методы для управления атрибутами могут

    Это замечание относится к сервлетам написанным под JSDK2.0: Методы для управления атрибутами могут оказаться полезными, если Вы удаляете обращения к методу getServlet. Эти методы, разработанные для сервлетов, которые вызывают метод getServlet и затем вызывают общедоступные методы отличные от метода service.

    Удаление обращений к методу getServlet из этих сервлетов включает:

  • Замените сервлет с обращением к методу getServlet на класс не являющийся сервлетом.


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


  • Замените все вызовы метода getServlet вызовами значения вышеуказанного атрибута.


  • Замените обращения к методам объекта Servlet на обращения к методам состояния возвращенного от атрибута.


  • Перенаправление запроса

    Как только Вы получаете объект RequestDispatcher, Вы можете дать возможность ассоциированному с ним ресурсу отвечать на запрос клиента. Перенаправление очень полезно, например, когда сервлет производит запрос, и ответ носит общий характер, так что он может быть передан другому ресурсу. Сервлет может, например, заведовать информацией кредитных карт, когда пользователь размещает заказ, и потом отправлять запрос клиента к заказу, который возвращает страницу "Спасибо за заказ". В примере Duke's Bookstore, сервлет BookStoreServlet получает сессию пользователя, а потом request dispatcher возвращает стартовую страницу магазина Duke's Bookstore:
    public class BookStoreServlet extends HttpServlet {
    public void service (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... // Получить или начать новую сессию пользователя
    HttpSession session = request.getSession(); // Открыть пользователю стартовую страницу
    dispatcher.forward(request, response);
    ... } }
    Запомните, что метод forward должен быть использован тогда, когда необходимо отдать другому ресурсу возможность отвечать пользователю. Если Вы уже получили доступ к объектам ServletOutputStream или PrintWriter, Вы не можете использовать этот метод; он вызовет исключение IllegalStateException.
    Если Вы уже начали отвечать пользователю, используя объекты PrintWriter или ServletOutputStream, Вам необходимо использовать метод .

    Получение объекта RequestDispatcher

    Чтобы получить доступ к объекту RequestDispatcher, используйте метод
    getRequestDispatcher класса ServletContext. Этот метод в качестве аргумента берет URL запрашиваемого ресурса. Формат этого аргумента последовательность имен директорий разбитых знаком слэш ("/"), и именем ресурса на конце. Вот следующие примеры возможных URL:
  • /servlet/myservlet

  • /servlet/tests/MyServlet.class

  • /myinfo.html

  • Например, когда сервлет BookStoreServlet получает объект RequestDispatcher для главной страницы магазина Duke's Bookstore:
    public class BookStoreServlet extends HttpServlet {
    public void service (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Получаем dispatcher; он получает главную страницу для пользователя
    RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( "/examples/applications/bookstore/bookstore.html");
    ... } }
    URL ресурса должен быть доступным на сервере, на котором запущен сервлет в момент обращения. Если ресурс недоступен, или у сервера не реализован объект RequestDispatcher для ресурса данного типа, этот метод вернет значение null. Сервлет должен быть готов к таким ситуациям. Сервлет BookStoreServlet делает это вот таким простым путем:
    public class BookStoreServlet extends HttpServlet {
    public void service (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Получаем dispatcher; он получает главную страницу для пользователя
    RequestDispatcher dispatcher = ...;
    if (dispatcher == null) { // No dispatcher means the html file can not be delivered response.sendError(response.SC_NO_CONTENT);
    } ... } }

    RemoveAttribute - удаление атрибута

    Любой сервлет может удалить атрибут из объекта ServletContext. Поскольку атрибуты являются совместно используемыми, Вам надо проявить осторожность, чтобы не удалить атрибут, который используется в этот момент другим сервлетом. Duke's Bookstore не использует метод removeAttribute.

    SetAttribute - установка атрибута

    Сервлеты устанавливают атрибуты, используя метод ServletContext.setAttribute; обычно это производится во время инициализации. Когда у Вас несколько сервлетов используют атрибут, каждый должен проинициализировать этот атрибут. А раз так, каждый сервлет должен проверить значение атрибута, и устанавливать его только в том случае если предыдущий сервлет не сделал этого.
    Следующий пример демонстрирует метод init сервлета CatalogServlet, который пробует установить совместно-используемый атрибут для магазина Duke's Bookstore:
    public class CatalogServlet extends HttpServlet {
    public void init() throws ServletException { BookDBFrontEnd bookDBFrontEnd = ...
    if (bookDBFrontEnd == null) { getServletContext().setAttribute( "examples.bookstore.database.BookDBFrontEnd", BookDBFrontEnd.instance());
    } } ... }
    Если сервлет установил атрибут, каждый другой сервлет в том же контексте может запрашивать его значение, переопределять это значение, или удалять атрибут.

    Совместное использование ресурсов сервлетами (JSDK 2.1)

    Сервлеты выполняемые на одном сервере иногда совместно используют ресурсы. Это справедливо для сервлетов, которые являются компонентами одного приложения, как, например, сервлеты магазина Duke's Bookstore. Сервлеты исполняемые на одном сервере могут совместно использовать ресурсы с помощью методов интерфейса ServletContext для манипулирования атрибутами: setAttribute, , и .
    Отметим что использование атрибутов - один из способов из предшествующих JSDK2.1 версий сервлетов.

    Связи сервлета

    Чтобы удовлетворять запросам клиентов, сервлеты иногда должны получать доступ к ресурсам сети: другим сервлетам, HTML страницам, объектам используемым совместно с другими сервлетами на том же сервере, и тому подобное.
    Если Вашему сервлету необходим доступ к сетевым ресурсам, таким, как сервлет работающий на другом сервере, он может послать HTTP запрос к тому сервлету. Этот урок, однако, покажет Вам что делать, если сервлету необходимы ресурсы доступные с вашего сервера:
    таких как сервлеты, HTML страницы, и так далее, с помощью объекта RequestDispatcher.
  • , где ресурсы это объекты Java, стало возможным через атрибуты.

  • с помощью объекта сервлета Servlet и вызова его общедоступных методов напрямую.


  • Включение ответа

    Метод include интерфейса RequestDispatcher позволяет вызываемому сервлету отвечать клиенту, но использовать в качестве части ответа ресурс, ассоциированный с объектом RequestDispatcher.
    Поскольку сервер вызывает метод RequestDispatcher.include подразумевается также, что он отвечет клиенту, сервлет будет использовать объекты PrintWriter и ServletOutputStream до или после вызова метода include. Вы должны запомнить, однако, что вызываемый ресурс не может устанавливать заголовки в ответе клиенту. Если ресурс попытается установить заголовки, нет гарантии, что они будут установлены.
    Следующий пример показывает, как бы выглядел сервлет ReceiptServlet, если бы, вместо простого благодарственного ответа пользователю за оставленный заказ, он также включал его список. Например, благодарит за заказ и включает список заказанного, который Вы должны полагать является псевдокодом:
    public class ReceiptServlet extends HttpServlet {
    public void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Выполняем заказ клиента
    ... // Благодарим за заказ
    res.setContentType("text/html"); PrintWriter toClient = res.getWriter(); ... toClient.println("Thank you for your order!");
    // Получаем request-dispatcher, чтобы послать список заказанного клиентом
    RequestDispatcher summary = getServletContext().getRequestDispatcher("/OrderSummary");
    // Опускаем список заказанного в случае ошибки
    if (summary != null) try { summary.include(req, res);
    } catch (IOException e) {} catch (ServletException e) {}
    toClient.println("Come back soon!"); toClient.println(""); toClient.close(); }

    Вызов сервлетов из сервлетов (JSDK 2.0)

    Чтобы Ваш сервлет вызвал другой сервлет, Вы можете:
  • Либо дать сервлету сделать HTTP запрос к другому сервлету. (Это относится к общему программированию на Java. Для более подробной информации, обратитесь к ресурсу Working with URLsВызов сервлетов из сервлетов (JSDK 2.0).)  

  • Либо сервлет может вызвать общедоступные методы другого сервлета напрямую, если оба сервлета запущены на одном и том же сервере.

  • Этот урок обсуждает второй из вышеуказанных пунктов. Чтобы вызвать общедоступный метод другого сервлета напрямую, Вам надо:
  • Знать имя сервлета, метод которого Вы хотите вызвать.

  • Получить доступ к объекту сервлета Servlet. 

  • Вызвать общедоступный метод.

  • Чтобы получить доступ к объекту Servlet, используйте метод getServlet класса ServletContext. Получите объект ServletContext из объекта ServletConfig, который находится в объекте Servlet. Пример поможет Вам разобраться. Когда сервлет BookDetail вызывает сервлет BookDB, сервлет BookDetail запрашивает объект
    Servlet сервлета BookDB вот так:
    public class BookDetailServlet extends HttpServlet {
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... BookDBServlet database = (BookDBServlet). getServletConfig().getServletContext().getServlet("bookdb"); ... } }
    Как только Вы получили объект сервлета, Вы можете вызывать любой общедоступный метод этого сервлета. Например, сервлет BookDetail вызывает метод getBookDetails сервлета BookDB:
    public class BookDetailServlet extends HttpServlet {
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... BookDBServlet database = (BookDBServlet). getServletConfig().getServletContext().getServlet("bookdb"); BookDetails bd = database.getBookDetails(bookId); ... } }
    Вам надо проявлять осторожность при вызове методов другого сервлета. Если сервлет, который Вы хотите вызывать, реализует интерфейс SingleThreadModel interface, Ваш вызов может нарушить природу однопотокового сервлета. (Сервер не может вмешаться и обеспечить, чтоб вызов был в момент, когда никто не взаимодействует с сервлетом.) В таком случае, Ваш сервлет должен использовать HTTP запрос к другому сервлету вместо прямых вызовов методов.

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

    Когда сервер загружает сервлет, сервер запускает метод сервлета init. Инициализация выполняется, прежде чем сервлет начнет обрабатывать запросы клиентов, и прежде чем сервлет будет уничтожен.
    И хотя сервлеты выполняются на много-потокотоковых серверах, у сервлета во время инициализации нет одновременно выполняющихся потоков. Сервер вызывает метод init один раз, затем сервер загрузит сервлет, и больше метод init не вызывается до тех пор, пока сервер не перезагрузит сервлет. Сервер не может перезагрузить сервлет до тех пор, пока он не уничтожит его, используя метод destroy.

    По умолчанию инициализация класса HttpServlet инициализирует сервлет и идентифицирует инициализацию. Чтобы проинициализировать сервлет определенным образом, переопределите метод init согласно той версии JSDK, которую используете: метод init(ServletConfig) для версии 2.0 и метод init() для версии 2.1. При переопределении метода init следуйте следующим правилам: 
  • В случае возникновения ошибки инициализации, которая приводит сервлет в состояние неработоспособности, вызывайте исключение UnavailableException.

    Как пример возникновения такого типа ошибок - невозможность установления необходимого сетевого соединения.

  • Не вызывайте метод System.exit. 

  • Только для версии 2.0: Сохраняйте параметр ServletConfig так, чтобы метод getServletConfig мог вернуть эту величину. Самый простой способ реализовать это - надо, чтобы новый метод init вызывал super.init.

  • Здесь приведен пример метода init для версии 2.1:
    public class BookDetailServlet ... {
    public void init() throws ServletException { BookDBFrontEnd bookDBFrontEnd = (BookDBFrontEnd)getServletContext().getAttribute( "examples.bookstore.database.BookDBFrontEnd");
    if (bookDBFrontEnd == null) { getServletContext().setAttribute( "examples.bookstore.database.BookDBFrontEnd", BookDBFrontEnd.instance()); } ... }
    Как видите метод init простой: он пытается получить параметр, и если параметр еще не получил значения, он создает его.
    Есть и другие инициализирующие задачи, которые сервлет может выполнять. Например, если сервлет использует базу данных, метод init может открыть соединение с ней и в случае неудачи вызвать исключение UnavailableException. Ниже приведен псевдокод о том, как мог бы выглядеть метод init:
    public class DBServlet ... {
    Connection connection = null;
    public void init() throws ServletException {
    // Соединяемся с базой данных перед запросами
    try { databaseUrl = getInitParameter("databaseUrl"); ...
    // Тем же способом берем параметры пользователя и пароля
    connection = DriverManager.getConnection(databaseUrl, user, password); } catch(Exception e) { throw new UnavailableException (this, "Could not open a connection to the database"); } } ... }

    Обеспечение "чистого" завершения

    Чтобы обеспечить "чистое" завершение, уничтожение не должно разрушать ни какие разделяемые ресурсы до тех пор, пока не завершатся все сервис-процессы. Один момент реализации этого, проверка счетчика выполняемых сервисов. Другой - заключается в оповещении "долгоиграющего" методов, что пора завершать работу. Это выполняет другая часть кода приведенная ниже. Например:
    public ShutdownExample extends HttpServlet { private boolean shuttingDown; ... //Методы доступа к процессам завершения
    protected void setShuttingDown(boolean flag) { shuttingDown = flag; } protected boolean isShuttingDown() { return shuttingDown; } }
    Ниже приведен пример метода destroy использующего вышеуказанные методы для обеспечения "чистого" завершения:
    public void destroy() {
    synchronized(lock) { /* Проверка на наличие ваполняемых сервисов, * и если таковые существуют, останавливаем их. */
    if (numServices() > 0) { setShuttingDown(true); }
    /* Ждем завершения всех сервисов. */
    while(numServices() > 0) { try { wait(); } catch (InterruptedException e) { } } } }

    Отслеживание сервисных запросов

    За слежением за сервисными запросами, включите код в ваш сервлет, который будет считать количество запущенных сервис методов. Этот код должен иметь доступные методы прибавления, вычитания и возвращать их значения. Потому как разные потоки будут обращаться к этим методам, и метод destroy будет ждать, пока их количество не станет равным нулю, доступ к этим методам должен быть синхронизированным. Объект lock с модификатором private это тот объект, с помощью которого производится синхронизация. Например:
    public ShutdownExample extends HttpServlet { private int serviceCounter = 0; private Object lock = new Object(); ... //Методы доступа к стетчику
    protected void enteringServiceMethod() { synchronized(lock) { serviceCounter++; } } protected void leavingServiceMethod() { synchronized(lock) { serviceCounter--; if (serviceCounter == 0 && isShuttingDown()) notifyAll(); } } protected int numServices() { synchronized(lock) { return serviceCounter; } } }
    Метод service должен вызывать метод увеличения счетчика каждый раз, когда метод начинает свое выполнение и вызывать метод уменьшения значения счетчика каждый раз, когда он возвращает значение. Вот один из вариантов того, как мог бы подкласс класса HttpServlet переопределить метод service. Переопределенный метод должен вызывать метод super.service для того, чтобы сохранить оригинальную функциональность метода HttpServlet.service.
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { enteringServiceMethod(); try { super.service(req, resp); } finally { leavingServiceMethod(); } }

    Параметры инициализации

    Вторая версия метода init вызывает метод getInitParameter. Этот метод использует имя параметра в качестве аргумента и возвращает строковое представление (String) величины этого параметра.
    (Спецификация инициализации параметров зависит от сервера. Например, параметры, устанавливающие свойства, когда сервлет выполняется с помощью servletrunner или сервером JSDK2.1. Урок содержит общее объяснение свойств и как их создавать.)
    Если по какой-то причине Вам потребуются имена параметров, используйте метод getParameterNames.

    Разработка аккуратных "долгоиграющих" методов

    Последняя деталь в обеспечении "чистого" завершения организовать аккуратное исполнение "долгоиграющих" методов. Методы, которые могут выполняться длительное время должны проверять значения методов предупреждающих о наступлении завершения, и при необходимости прерывать работу. Например:
    public void doPost(...) { ... for(i = 0; ((i < lotsOfStuffToDo) && !isShuttingDown()); i++) { try { partOfLongRunningOperation(i); } catch (InterruptedException e) { } } }

    Уничтожение сервлета

    Метод destroy позволяет классу the HttpServlet уничтожить сервлет и индифицировать уничтожение. Чтобы уничтожить любые связанные с севлетом ресурсы, переопределите метод destroy. Метод destroy должен отменить любой инициализирующий процесс и синхронизировать установившийся статус с текущим статусом в памяти.
    Следующий пример показывает метод destroy, который сопровождает псевдокод метода init из предыдущего урока:
    public class DBServlet ... { Connection connection = null;
    ... // Метод init
    public void destroy() { // Закрываем соединение и подготавливаем объект для сборщика мусора
    connection.close(); connection = null; } }
    Сервер вызывает метод destroy после того, как завершатся все вызовы сервиса, или пройдет определенный промежуток времени устанавливаемый сервером, что быстрее произойдет. Если Ваш сервлет производит какую-либо "долгоиграющую" операцию, метод service может продолжать выполняться в тот момент, когда сервер вызовет метод destroy. Вы ответственны за то, чтоб быть уверенным что, эти процессы должны быть завершены. Следующий урок
    покажет Вам как.
    Метод destroy описанный выше в примере предполагает, что все клиентские транзакции были завешены на тот момент, когда был вызван метод destroy, потому как сервлет не использовал "долгоиграющих" операций.

    Сервлет выполняется до тех пор, пока сервер не уничтожит его, например, по запросу системного администратора. Когда сервер уничтожает сервлет, сервер запускает метод сервлета destroy. Этот метод запускается один раз; сервер не будет запускать метод destroy опять, до тех пор, пока сервер не перезагрузит этот сервлет и не проинициализирует.
    В момент, когда сервер вызывает метод destroy, другой поток может принимать запрос. Урок Управление сервисными потоками во время выключения сервлета расскажет Вам, как произвести "чистое" выключение в случаях, когда могут выполняться "долгоиграющие" потоки запросов.

    Управление сервисными потоками в момент выключения сервлета

    Все методы сервлета service должны завершаться к моменту завершения работы сервлета. Сервер пытается обеспечить это, вызывая метод destroy либо после того, как все сервис-запросы будут возвращены, либо по завершению установленного сервером времени ожидания, что быстрее произойдет. Если Ваш сервлет использует операции, занимающие длительное время выполнения (это операции, выполнение которых превышает время ожидания сервера), процесс может быть не завершен в момент, когда сервер вызовет метод destroy. И вы должны обеспечить, чтобы все потоки управляющие клиентскими запросами, были завершены. В этом разделе обсуждается, как это реализовать.
    Если у Вашего сервлета существуют потенциальные "долгоиграющие" сервисные запросы придерживайтесь следующих правил:
  • Следите за тем как много потоков запущено методом service. 

  • Обеспечьте чистое завершение метода destroy, уведомляя "долгоиграющие" процессы о закрытии и ждите их завершения. 

  • Обеспечить "долгоиграющие" процессы возможностью периодической проверки о закрытии сервлета, и в случае такой необходимости: останавливать работу, очищаться и возвращать значения.


  • Жизненный цикл сервлета

    У каждого сервлета один и тот же жизненный цикл:
  • Сервер загружает и инициализирует сервлет 

  • Сервлет ни кого не обслуживает или обслуживает одного и более клиентов 

  • Сервер удаляет сервлет

    (некоторые сервера делают это, только когда их выключают)

  • Жизненный цикл сервлета

    Взаимодействия с клиентами

    После инициализации, сервлет готов к управлению запросами клиента. Эта часть жизненного цикла сервлета обсуждалась предыдущем уроке.
     

    Dtime

    Acrobat Distiller 3.0 for Windows
    25 February 2001 г. at 0:07
    =====================================================
    Watched Folder Frequency = 10 seconds
    After Distilling, PostScript Files = Moved
    Compatiblity Level = 3.0
    Generating ASCII Format Files = ON
    Default Page Width = 612
    Default Page Height = 792
    Default Page Units = Points
    Default Resolution = 600
    Text and Graphics LZW Compression = ON
    Color Image Downsample to = ON
    Color Image Downsample to Resolution = 72
    Color Image Automatic Filter Selection = ON
    Color Image Compression = OFF
    Color Image Compression Using = JPEG Medium
    Grayscale Image Downsample to = ON
    Grayscale Image Downsample to Resolution = 72
    Color Image Automatic Filter Selection = ON
    Grayscale Image Compression = OFF
    Grayscale Image Compression Using = JPEG Medium
    Monochrome Image Downsample to = ON
    Monochrome Image Downsample to Resolution = 300
    Monochrome Image Compression = ON
    Monochrome Image Compression Using = CCITT Group 4
    Subset Embedded Fonts = ON
    Maximum Subset Percentage = 35
    Embed All Fonts = ON
    Use Prologue/Epilogue = OFF
    Preserve OPI Comments = OFF
    Color Conversion Method = Unchanged
    Apply Transfer Functions
    Apply Under Color Removal / Black Generation Functions
    Preserve Overprint Settings = OFF
    Preserve Halftone Screen Info = OFF
    Convert CMYK Images To RGB = ON
    =====================================================

    Архитектура пакета Servlet

    Пакет javax.servlet предоставляет интерфейсы и классы для написания сервлетов. Ниже приводится описание пакета.
     

    Архитектуру пакета servlet

    рассматривает назначение основных интерфейсов и объектов пакета servlet.

    Дополнительные возможности HTTP сервлетов

    Классы и интерфейсы описанные выше составляют обычный сервлет. HTTP сервлет обладает некоторыми дополнительными объектами, которые предоставляют возможности отслеживания сессии. Разработчик может использовать эти интерфейсы для поддержания статуса между сервлетом и клиентом, который сохраняется через множественные соединения в течение определенного периода времени. HTTP сервлеты также имеют объекты, которые работают с закладками (cookie). Разработчик использует интерфейс закладок для того, чтобы сохранять данные у клиента и получать эти данные обратно.

    Другие применения сервлетов

    Ниже перечислены некоторые из множества применений для сервлетов:
  • Организация сотрудничества между людьми. Сервлет может поддерживать множество запросов одновременно и может синхронизировать запросы. Это позволяет сервлетам поддерживать такие системы, как онлайн конференции.

  • Перенаправление запросов. Сервлеты могут перенаправлять запросы к другим серверам или сервлетам. Такие сервлеты могут использоваться для сбалансирования нагрузки между несколькими серверами, которые зеркально отображают одно и тоже содержание, и разбиения единственного логического сервиса на несколько серверов, согласно типу задачи или организационным границам.

  •  

    Готовимся к написанию

    Для того чтобы подготовиться к написанию, этот урок обсудит:

    Handling GET and POST Requests

    To handle HTTP requests in a servlet, extend the HttpServlet class and override the servlet methods that handle the HTTP requests that your servlet supports. This lesson illustrates the handling of GET and POST requests. The methods that handle these requests are doGet and doPost.

    Handling GET requests

    Handling GET requests involves overriding the doGet method. The following example shows the BookDetailServlet doing this. The methods discussed in the section are shown in bold.

    public class BookDetailServlet extends HttpServlet {
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... // set content-type header before accessing the Writer response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    // then write the response out.println("" + " Book Description" + ...);
    //Get the identifier of the book to display String bookId = request.getParameter("bookId");
    if (bookId != null) { // and the information about the book and print it ... } out.println(""); out.close();
    } ... }
    The servlet extends the HttpServlet class and overrides the doGet method.
    Within the doGet method, the getParameter
    method gets the servlet's expected argument.
    To respond to the client, the example doGet method uses a Writer from the HttpServletResponse object to return text data to the client. Before accessing the writer, the example sets the content-type header. At the end of the doGet method, after the response has been sent, the Writer is closed.

    Handling POST Requests

    Handling POST requests involves overriding the doPost
    method. The following example shows the ReceiptServlet doing this. Again, the methods discussed in the section are shown in bold.

    public class ReceiptServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... // set content type header before accessing the Writer response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    // then write the response out.println("" + " Receipt " + ...);
    out.println("

    Thank you for purchasing your books from us " + request.getParameter("cardname") + ...); out.close();
    } ... }
    The servlet extends the HttpServlet class and overrides the doPost method.
    Within the doPost method, the getParameter
    method gets the servlet's expected argument.
    To respond to the client, the example doPost method uses a Writer from the HttpServletResponse object to return text data to the client. Before accessing the writer the example sets the content-type header. At the end of the doPost
    method, after the response has been set, the Writer is closed.
    Handling POST Requests



    >
    >



    Интерфейс сервлета

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

    Интерфейс ServletRequest

    Интерфейс ServletRequest предоставляет сервлету доступ к:
  • Такой информации как имена параметров предоставляемых клиентом, протокол (схема) используемый клиентом, и имена удаленного хоста, который выполнил запрос и сервера, который его получил 

  • Входной поток, ServletInputStreamИнтерфейс ServletRequest. Сервлеты используют входной поток для получения данных от клиентов, которые используют протоколы уровня приложений, такие как методы HTTP POST и PUT.

  • Интерфейсы, наследующие интерфейс ServletRequest позволяют сервлетам получать более специфичные данные протокола. Например, интерфейс HttpServletRequestИнтерфейс ServletRequest содержит методы для получения специальной информации HTTP заголовков.
     

    Интерфейс ServletResponse

    Интерфейс ServletResponse предоставляет сервлету методы, для отправки сообщений клиенту. Он:
  • Позволяет сервлету установить длину содержимого и тип MIME ответа. 

  • Устанавливает выходной поток, ServletOutputStreamИнтерфейс ServletResponse, и Writer через который сервлет может отправить данные ответа.

  • Интерфейсы, наследующие интерфейс ServletResponse предоставляют сервлетам более специфичные возможности. Например, интерфейс HttpServletResponseИнтерфейс ServletResponse содержит методы позволяющие сервлету манипулировать специальной информации HTTP заголовков.
     

    Использование сервлетов вместо CGI скриптов!

    Сервлеты являются эффективным заменителем CGI скриптов. Они дают дорогу к генерации динамических документов, которые легче писать и быстрее выполнять. Сервлеты также обходят проблему программирования серверов с платформозависимыми интерфейсами прикладного программирования: они разрабатываются на стандартном расширении Java - Java Servlet API.
    Итак, используем сервлеты для обработки клиентских HTTP запросов. Например, сервлет обрабатывающий данные, посланные POST запросом по HTTP из HTML формы, включающие заказ или данные кредитной карточки. Сервлет вроде этого мог бы быть частью системы приема и обработки заказов, работающий с базой данных продуктов и инвентаря, и возможно с онлайновой системой оплаты.
     

    Примеры сервлетов обсуждаемые в этих уроках

    Расскажет о примерах, которые будут обсуждаться в последующих уроках.

    Примеры сервлетов

    Примеры сервлетов
    Последующие уроки расскажут вам, как писать HTTP сервлеты. Для этого потребуются некоторые знания HTTP протокола; чтобы узнать подробнее о HTTP протоколе, Вы можете ознакомиться с документом RFC for HTTP/1.1Примеры сервлетов.
    Урок использует пример Duke's Bookstore, простой онлайн книжный магазин который позволяет пользователям производить различные функции. Каждая функция обеспечивается сервлетом:

     
    Функция
    JSDK2.0 Servlet
    JSDK2.1 Servlet
    Просматривание книг выставленных на продажу CatalogServletПримеры сервлетов CatalogServletПримеры сервлетов
    Отбор книг, для покупки помещая их в "тележку" CatalogServletПримеры сервлетов CatalogServletПримеры сервлетов
    Получение более подробной информации о книге BookDetailServletПримеры сервлетов BookDetailServletПримеры сервлетов
    Управление базой данных книжного магазина BookDBServletПримеры сервлетов
    Просмотр книг отобранных для покупки ShowCartServletПримеры сервлетов ShowCartServletПримеры сервлетов
    Удаление книг из тележки ShowCartServletПримеры сервлетов ShowCartServletПримеры сервлетов
    Покупка книг отобранных в тележку CashierServletПримеры сервлетов CashierServletПримеры сервлетов
    Получение благодарности за сделанный заказ ReceiptServletПримеры сервлетов ReceiptServletПримеры сервлетов

    Урок использует сервлеты, чтобы продемонстрировать различные задачи. Например, сервлет BookDetailServlet используется, чтобы пояснить Вам, как управлять HTTP запросами GET, а сервлет CatalogServlet покажет вам отслеживание сессии.
    Набор файлов исходных текстов, входящих в состав примера Duke's Bookstore. Для Вашего удобства, мы включили два загружаемых zip архива: один содержит все файлы исходных текстов необходимых для построения и выполнения примера, используя Java Servlet Development Kit (JSDK) версии 2.0, другой содержит все файлы исходных текстов необходимых для построения и выполнения примера используя JSDK2.1.
    Чтобы запустить пример, вначале запустите процесс, который запустит сервлеты, такие как servletrunner из JSDK 2.0 или the server из JSDK 2.1. Как только процесс будет запущен, вызывайте сервлет из броузера.

    Простой сервлет

    Ниже приведенный класс полностью определяет сервлет: 
    public class SimpleServlet extends HttpServlet
    { // Управляет HTTP методом GET, генерируя простую web страницу.
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out; String title = "Simple Servlet Output";
    // Вначале устанавливаем тип содержимого и другие заголовкиe
    response.setContentType("text/html"); // Затем пишем ответ
    out = response.getWriter(); out.println(" "); out.println(title); out.println(""); out.println("

    " + title + "

    "); out.println("This is output from SimpleServlet."); out.println(""); out.close(); } }
    Вот он!
    Классы, упомянутые в разделе Архитектура пакета Servlet, выделены жирным шрифтом:
  • SimpleServlet наследует класс HttpServlet, который реализует и интерфейс Servlet. 

  • SimpleServlet переопределяет метод doGet класса HttpServlet. Метод doGet вызывается, когда клиент осуществляет GET запрос (HTTP запрос по умолчанию), и выводит простую HTML страницу, возвращаемую клиенту 

  • В самом методе doGet:
  •  
  • Запрос пользователя представлен объектом HttpServletRequest. 

  • Ответ пользователю представлен объектом HttpServletResponse. 

  • Так как ответом является текстовая информация, ответ посылается, используя объект Writer полученный от объекта HttpServletResponse.


  • Обзор сервлетов

    Сервлеты это модули расширения для запрос-ответ ориентированных серверов, таких как web сервера с поддержкой Java. Например, сервлет ответственный за передачу информации из HTML форм для обновления базы данных компании.
    Обзор сервлетов
    Сервлет для сервера то же самое, что апплет для броузера. Но в отличие от апплета сервлеты не имеют графического интерфейса.
    Сервлеты могут быть встроены в различные сервера, потому как интерфейс, который используется для написания сервлетов, не знает ничего о среде сервера или протоколе. Сервлеты становятся одними из самых распространенных среди HTTP серверов; много web серверов поддерживают интерфейс сервлетов.
     

    Взаимодействие с клиентом

    Когда сервлет принимает сигнал от клиента, он получает два объекта:
  • Объект ServletRequestВзаимодействие с клиентом, который устанавливает связь от клиента к серверу. 

  • Объект ServletResponseВзаимодействие с клиентом, который устанавливает связь от сервлета обратно к клиенту.

  • ServletRequest и ServletResponse интерфейсы пакета javax.servlet.
     

    Файл свойств

    Свойства хранятся в текстовом файле с именем по умолчанию servlets.properties для пакета JSDK2.1 и servlet.properties для пакета JSDK2.0. Файл содержит свойства для всех сервлетов, которые будут запущены с помощью утилиты выполнения сервлетов. Вот, например, файл свойств для магазина Duke's Bookstore:
    # Этот файл содержит свойства сервлетов из примера Duke's Bookstore.
    #-------------------------------------------------------------------
    # Главная страница Duke's Bookstore
    bookstore.code=BookStoreServlet
    # Просмотр всех книг магазина
    catalog.code=CatalogServlet
    # Информация по конкретной книге
    bookdetails.code=BookDetailServlet
    # Просмотр книг, выбранных для покупки
    showcart.code=ShowCartServlet
    # Собираем информацию для покупки выбранных книг
    cashier.code=CashierServlet
    # Выставляем счет пользователю купившему книги
    receipt.code=ReceiptServlet

    Инициализационные параметры

    Параметр свойства имя.initParams содержит параметры инициализации сервлета для пакета JSDK2.1. Для сервлетов пакета JSDK2.0, - свойство servlet.имя.initArgs. (в этой части обсуждаются имена свойств пакета JSDK2.1.)
    Синтаксис одного инициализационного параметра: имяПараметра
    = значениеПараметра. Данное свойство (данная пара ключ-значение) должно представлять одну логическую линию. Для читабельности, Вы можете использовать backquote-синтаксис, чтобы свойство могло занимать несколько линий в файле. Например, если магазин берет начальный HTML файл как параметр, начальный аргумент сервлета может выглядеть так:
    servlet.bookdb.initArgs=\ mainFile=examples/bookstore/Bookstore.html
    Множественные инициализационные параметры разделяются запятой. Например, сервлет BookDetail получает информацию о книге, соединяясь с реальной базой данных, его начальные аргументы могут выглядеть так:
    bookdetails.initParams=\ user=duke,\ password=dukes_password,\ url=fill_in_the_database_url

    Класс Servlet

    В этом разделе используются укороченные имена свойств пакета JSDK2.1. Если вы используете JSDK2.0, добавляйте "servlet." в начало имени свойств.
    Свойство, которое ассоциирует имя Вашего сервлета с именем класса сервлета это имя.code. Значение этого свойства - полное имя класса сервлета, включая пакет. Например, если бы классы магазина Duke Bookstore, были в пакете examples.bookstore, сервлет CatalogServlet включал бы свойство:
    catalog.code=examples.bookstore.CatalogServlet
    Свойство имя.code именует Ваш сервлет, ассоциируя имя (в данном примере, catalog) с классом (в данном примере, examples.bookstore.CatalogServlet).

     

    Подготовить к запуску JSDK сервер

    Прежде чем Вы запустите JSDK сервер, Вам надо иметь подходящую JDK:
  • Для Sparc Solaris 2.6, пакет JSDK был тестирован с версией JDK 1.1.7 & Java2 SDK 1.2

  • Для Windows98/NT, пакет JSDK был тестирован с версией JDK 1.1.7 & Java2 SDK 1.2

  • Также можно
    сконфигурировать различные свойства JSDK сервера, прежде чем Вы его запустите. Эти свойства включают порт сервера, по умолчанию установленный - 8080, имя хоста сервера, по умолчанию установленный - localhost, и корневой каталог (root), по умолчанию установленный в поддиректории веб страниц (webpages) установленного пакета JSDK. Чтобы просмотреть или изменить данные конфигурационные значения, откройте файл default.cfg в директории, где проинсталлирован JSDK.
    И последнее, запомните, что директория с сервлетами находится:
    doc_root/WEB-INF/servlets

    Свойства сервлета

    Свойства это пары переменных состоящие из ключа и его значения, использующиеся для установки конфигурации, создания и инициализации сервлета. Например, в пакете JSDK2.0 servlet.catalog.code=CatalogServlet является свойством, где servlet.catalog.code это ключ со значением CatalogServlet. В пакете JSDK2.1 тоже свойство называется catalog.code=CatalogServlet - свойство, у которого catalog.code это ключ со значением CatalogServlet.
    Использование свойств требует от Вас дать имя сервлету. (Строка catalog в имени свойств приведенных выше это имя каталога сервлета.) Имя сервлета дает возможность программе, которая выполняет сервлет, правильно ассоциировать свойства с соответствующими сервлетами. А так же это имя, которое клиент будет использовать, чтобы получить доступ к Вашему сервлету.
    Утилиты для запуска сервлетов из пакета JSDK содержат два свойства для сервлетов. Они ассоциируют имя, которое Вы выбрали для Вашего сервлета с:
  • именем класса сервлета

  • любыми инициализационными параметрами, которые требуются сервлету

  •  

    Утилита servletrunner

    Написанный сервлет может быть проверен с помощью утилиты включенной в пакет JSDK. Пакет JSDK 2.0 содержит утилиту servletrunner, в то время как JSDK 2.1 приходит с упрощенным вариантом HTTP сервера. В этом уроке обсуждается, как установить и запустить эти утилиты.
     

    Установка свойств сервлета

    Вам надо описать некоторые детали, чтобы запустить сервлет. Например, если сервлет требует инициализационные параметры, вам потребуется установить эти данные, прежде чем запускать процесс JSDK, который запустит ваш сервлет.
     

    Выключение JSDK сервера

    Чтобы остановить выполнение сервера, пакет JSDK предоставляет команды выключения в той же директории, где и команды для запуска (директория, куда проинсталлирован пакет JSDK).
    Следующей командой выключаете сервер под Unix:
    % stopserver
    А такой командой выключаете сервер под Windows:
    C:\jsdk\> stopserver

    Запуск JSDK сервера

    Чтобы запустить сервер, используйте под Unix Korn-shell скрипт или под Windows .bat файл, который находится в директории, куда проинсталлирован пакет JSDK.
    Следующей командой запускается сервер под Unix:
    % startserver
    А такой командой запускается сервер под Windows:
    C:\jsdk\> startserver
    Как только JSDK сервер запущен, Вы можете использовать его для проверки своих сервлетов.

    Запуск сервера (JSDK 2.1)

    После того, как будет установлен файл свойств, вы можете запускать сервлеты на сервере прилагаемом к пакету JSDK2.1. В этом разделе обсуждается, как это сделать.
     

    Запуск сервера (JSDK2.1)

    Так же как утилита servletrunner из пакета JSDK2.0, сервер включенный в пакет JSDK2.1 прост, он поддерживает многопотоковые процессы, которые могут быть запущены одним или несколькими сервлетами.
    В отличие от некоторых веб-серверов, JSDK сервер не перегружает автоматически обновленные сервлеты. Хотя вы можете остановить и перезапустить сервер, чтобы запустить новую версию сервлета.
    В этом разделе вы узнаете как:




  • Запуск servletrunner (JSDK 2.0)

    После того, как будет установлен файл свойств, вы можете запускать сервлеты с помощью утилиты servletrunner прилагаемой к пакету JSDK2.0. В этом разделе обсуждается, как это сделать.

    Запуск servletrunner (JSDK2.0)

    Утилита servletrunner находится в директории /bin. Вам буде проще запустить эту утилиту, если к директории будет прописан путь. Например:
    % setenv PATH /usr/local/jsdk/bin: (для UNIX) C> set PATH=C:\jsdk\bin;%PATH% (для Win32) export PATH=/usr/local/jsdk/bin:$PATH (для Linux) - от переводчика
    Выполняя servletrunner с ключом -help, Вы получите инструкции по использованию, не запуская саму утилиту:
    % servletrunner -help Usage: servletrunner [options] Options: -p port the port number to listen on -b backlog the listen backlog -m max maximum number of connection handlers -t timeout connection timeout in milliseconds -d dir servlet directory -r root document root directory -s filename servlet property file name -v verbose output %
    Чтобы просмотреть установки этих величин по умолчанию, запустите servletrunner с ключом -v. Команда запускает утилиту; просто остановите ее, после того, как Вы получите информацию, если Вы еще не готовы использовать ее или хотите запустить с другими параметрами. На Unix, например, Вы можете использовать команду kill, чтобы остановить выполнение servletrunner.
    % servletrunner -v Server settings: port = 8080 backlog = 50 max handlers = 100 timeout = 5000 servlet dir = ./examples document dir = ./examples servlet propfile = ./examples/servlet.properties
    Замечание: В значениях по умолчанию, выведенных выше, в директориях servlet dir, document dir и директории servlet propfile содержится точка ("."). Точка предполагает текущую директорию выполнения. Текущей директорией выполнения обычно является директория, из которой была запущена программа. В данном случае, однако, точка означает директорию, где установлен
    JSDK.
    Если Вы запустите утилиту servetrunner из другой директории, утилита servletrunner первым делом сменит ее текущую рабочую директорию (и, в следствии, то, что Вы считали точкой).
    Как только утилита servletrunner будет запущена, Вы можете использовать ее для проверки своих сервлетов.

    

        Бизнес: Предпринимательство - Малый бизнес - Управление