Класс HttpServlet

Пакеты сервлетов включают два абстрактных класса, которые реализуют интерфейс Servlet: класс GenericServlet (из пакета javax.servlet) и класс HttpServlet (из пакета javax.servlet.http). Эти классы предоставляют реализацию по умолчанию для всех методов интерфейса Servlet. Большинство разработчиков используют либо класс GenericServlet, либо класс HttpServlet, и замещают некоторые или все методы.

Сервлеты, работающие с клиентами через Web, обычно расширяют класс HttpServlet. Метод service, как правило, переопределяется, чтобы иметь возможность различать стандартные методы запросов, получаемые от Web-браузера клиента. Двумя наиболее распространенными типами запросов HTTP (их также называют методами запросов) являются get и post. Запрос get получает (или извлекает) информацию. Запрос post помещает (или отправляет) данные на сервер. Типичное применение метода post - отправка на сервер информации для аутентификации, или данных из формы, в которую пользователь ввел информацию.

В классе HttpServlet определены методы doGet и doPost для реакции на запросы типа get и post клиента. Эти методы вызываются методом service класса HttpServlet, который, в свою очередь, вызывается при поступлении запроса на сервер. Метод service сначала определяет тип запроса, а затем вызывает соответствующий метод. Имеются и другие, менее употребительные типы запросов, но в данной статье они не рассматриваются.

Методы doGet и doPost принимают в качестве параметров объекты HttpServletRequest и HttpServletResponse, которые дают возможность осуществлять взаимодействие между клиентом и сервером. Методы интерфейса HttpServletRequest облегчают доступ к данным запроса. Методы интерфейса HttpServletResponse облегчают возврат результатов Web-клиенту в виде HTML.

Интерфейс HttpServletRequest

При каждом вызове методы doGet и doPost класса HttpServlet принимают в качестве параметра объект, который реализует интерфейс HttpServletRequest. Web-сервер, который исполняет сервлет, создает объект HttpServletRequest и передает его методу service сервлета (который в свою очередь передает его методу doGet или doPost). Данный объект содержит запрос, поступивший от клиента.

Имеется множество методов, дающих возможность сервлету обрабатывать клиентский запрос. Некоторые из этих методов принадлежат интерфейсу ServletRequest - интерфейсу, который расширяется интерфейсом HttpServletRequest. Ряд ключевых методов, использованных в примерах, представлены в таблице. Полный список методов интерфейса HttpServletRequest можно найти в документации компании Sun.

МетодОписание
String getParameter(String name) Получение из запроса значения параметра. Наименование параметра определено значением name.
Enumeration getParameterNames() Получение из запроса имен всех параметров.
String[ ] getParameterValues(String name) Для параметра с несколькими значениями данный метод возвращает строковый массив.
Cookie[ ] getCookies () Получение массива объектов Cookie, сохраненных на компьютере клиента. Cookie могут быть использованы для уникальной идентификации клиента сервером.
HttpSession getSession(boolean create) Возвращает объект HttpSession текущего сеанса клиента. Если параметр create равен true и объект HttpSession не существует, то создается новый объект HttpSession.

Интерфейс HttpServletResponse

При каждом обращении к сервлету методы doGet и doPost класса HttpServlet принимают объект, который реализует интерфейс HttpServletResponse. Web-сервер, исполняющий сервлет, создает объект HttpServletResponse и передает его методу service сервлета (который в свою очередь передает его методу doGet или doPost). Интерфейс HttpServletResponse определяет ответ клиенту.

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

МетодОписание
void addCookie (Cookie cookie) Метод используется для добавления Cookie в заголовок ответа клинту. Установленный максимальный возвраст Cookie, а также разрешение клиентом хранения Cookie определяют, будут ли Cookies сохранены на клиенте и время их хранения.
ServletOutputStream getOutputStream() Получение бинарного потока вывода для отправления бинарных данных клиенту.
PrintWriter getWriter Получение символьного потока вывода для отправления текстовых данных клиенту.
void setContentType(String type) Определение MIME-типа ответа браузеру. MIME-тип помогает браузеру определить, как отображать данные. Например, MIME-тип "text/html" указывает, что ответ является HTML-документом, поэтому браузер отображает HTML-страницу.

Пример сервлета RequestServlet

В примере рассматривается использование некоторых методов интерфейса HttpServletRequest для формирования ответа клиенту информации о запросе, отправленным методом GET, и генерации ответа клиенту. Пример сервлета включает сам сервлет RequestServlet.java и дескриптор приложения web.xml. Структура примера сервлета в IDE Eclipse представлена на следующем скриншоте.

Листинг сервлета RequestServlet.java

Приведенный ниже код реализует простой сервлет RequestServlet.java, включающий 2 вспомогательных внутренних класса и возвращающий статическую HTML-страницу браузеру. Cервлет RequestServlet наследует свойства HttpServlet, реализующего интерфейс Servlet.

import java.util.Enumeration;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.servlet.annotation.WebServlet;

class ClickOutput 
{
    public static int printClick(PrintWriter out, int count) 
    {
        out.print(++count + " -е обращение." + "<br>");
        return count;
    }
}
class RequestInfo
{
    static String br = "<br>";
    public static void printToBrowser(PrintWriter out, 
                                      HttpServletRequest req)
    {
        out.println("Method: " + req.getMethod());
        out.print(br + "Request URI: " + req.getRequestURI());
        out.print(br + "Protocol: " + req.getProtocol());
        out.print(br + "PathInfo: " + req.getPathInfo());
        out.print(br + "Remote Address: " + req.getRemoteAddr());
        // Извлечение имен заголовочной информации запроса
        Enumeration<String> e = req.getHeaderNames();
        out.print(br + "Header INFO: ");
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            String value = req.getHeader(name);
            out.print(br + name + " = " + value);
        }
    }
}
@WebServlet("/RequestServlet")
public class RequestServlet extends HttpServlet
{
    private static final long serialVersionUID = 1L;
    // счётчик подключений к сервлету
    private int count = 0;

    public RequestServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
                         throws ServletException, IOException {
        performTask(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
                         throws ServletException, IOException {
        performTask(request, response);
    }
    private void performTask(HttpServletRequest req, HttpServletResponse resp)
			             throws ServletException
    {
        try {
            // установка MIME-типа содержания ответа
            resp.setContentType("text/html; charset=UTF-8");
            // поток для данных ответа
            PrintWriter out = resp.getWriter();
            count = ClickOutput.printClick(out, count);
            // обращение к классу бизнес-логики
            if(count == 1)
                RequestInfo.printToBrowser(out, req);
            // закрытие потока
            out.close();
        } catch (UnsupportedEncodingException e) {
            System.err.print("UnsupportedEncoding");
        } catch (IOException e) {
            System.err.print("IOException");
        }
    }
}

При обращении к сервлету вызывается метод performTask, который формирует страницу ответа и передает ее в браузер через HttpServletResponse. В первых строках ответа сервера определен заголовок Content-Type с указанием кодировки UTF-8.

Листинг дескриптора приложения web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
                             http://java.sun.com/xml/ns/j2ee
                             http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         id="WebApp_9" version="2.4">
  <display-name>Servlet Request Info</display-name>
  <servlet>
    <servlet-name>info</servlet-name>
    <servlet-class>example.RequestServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>info</servlet-name>
    <url-pattern>/info</url-pattern>
  </servlet-mapping>
</web-app>

В дискрипторе приложения web.xml определяется сервлет (наименование <servlet-name> и класс <servlet-class>). Для запуска примера сервлета из среды IDE Eclipse необходимо стартовать сервер приложений и в адресной строке браузера ввести следующую строку :

http://localhost:8080/ServletInfo/info

Браузер отобразит нам информацию о запросе.

Скачать пример

Исходный код примера сервлета RequestServlet, рассмотренного в тексте страницы, можно скачать здесь (193 Кб).

  Рейтинг@Mail.ru