В этом посте мы разберемся как создать самое простое web-приложение на Java. Для разработки web-приложений я использую IDE NetBeans 6.7. Итак, к делу.

Чтобы создать web-приложение в NetBeans, зайдите в меню File->New Project… В появившемся окне в списке Categories выберите Java Web после чего в списке Projects щелкните на Web Application. Нажмите Next.

В следующем окне нужно указать имя и расположение проекта в файловой системе. Установим имя для нашего проекта в test-servlet, а расположение оставим по умолчанию. Все остальные настройки также оставляем как есть.

В следующем диалоговом окне необходимо выбрать сервер, на котором будет выполняться наше web-приложение. Я выбрал Apache Tomcat 6.0.18. В выпадающем списке Java EE Version выберите Java EE 5, а Context path оставим без изменений (/test-servlet). Жмем Finish. На этом создание web-приложения закончено. Можно нажать F6 или кнопку Run Main Project и посмотреть на результат нашей с Вами работы. В браузере должна открыться страница со словами “Hello World!”.

Вторым шагом будет создание сервлета, являющегося частью web-приложения.

Для начала создадим в Source Packages структуру пакетов нашего приложения. У меня это ru.topcode.testserv.

Что такое сервлет? Сервлет – это класс Java, предназначенный для динамического формирования содержимого ответа на запрос клиента по сети. Сервлеты часто называют web-компонентами. Они выполняются в специальной среде исполнения, создаваемой контейнером сервлетов или web-контейнером, таким, как Tomcat.

Сервлеты устанавливаются в web-контейнерах как часть web-приложения. Такие приложения по сути являются набором web-ресурсов: HTML-страниц, изображений, мультимедийных данных, сервлетов, JSP, XML-файлов конфигурации, классов и библиотек поддержки Java. После развертывания web-приложения в web-контейнере контейнер создает и загружает экземпляр класса сервлета в виртуальную машину Java (JVM) для обслуживания запросов, поступающих на сервер.

Сервлет обслуживает каждый запрос в отдельном потоке. Таким образом, создатели сервлетов должны сами решать, надо ли обеспечивать синхронизацию доступа к переменным экземпляра и переменным класса или нужно использовать разделяемые ресурсы, например соединение с БД, в зависимости от того, как эти ресурсы используются.

Все сервлеты реализуют интерфейс javax.servlet.Servlet. Разработчики web-приложений обычно пишут сервлеты, расширяющие javax.servlet.http.HttpServlet – абстрактный класс, который реализует интерфейс Servlet и создан специально для обслуживания HTTP-запросов. При создании web-контейнером экземпляра сервлета, осуществляются следующие действия.

  1. Контейнер вызывает метод init() сервлета, который предназначен для инициализации ресурсов, необходимых сервлету. Метод init() вызывается один раз за время жизни сервлета.
  2. Метод init() инициализирует объект, реализующий интерфейс javax.servlet.ServletConfig. Этот объект открывает сервлету доступ к параметрам инициализации, объявленным в дескрипторе развертывания. ServletConfig также открывает сервлету доступ к объекту javax.servlet.ServletContext, с помощью которого сервлет может протоколировать события, перенаправлять запросы к другим web-компонентам и получать доступ к прочим web-ресурсам этого же приложения. Разработчикам не нужно реализовывать метод init() в своих подклассах класса HttpServlet.
  3. При запросе к сервлету контейнер вызывает метод service() сервлета. В терминах HttpServlet, метод service() для обработки запроса автоматически вызывает подходящий HTTP-метод сервлета: doPost() или doGet(). Например, при посылке от пользователя HTTP-запроса POST сервлет отзывается выполнением метода doPost().
  4. При вызове двух главных методов сервлета HttpServlet (doPost() или doGet()) контейнер сервлета создает объекты javax.servlet.http.HttpServletRequest и javax.servlet.http.HttpServletResponse и передает их в качестве параметров этим методам обработки запроса. Объект HttpServletRequest представляет исходный запрос, а HttpServletResponse инкапсулирует ответ сервлета на этот запрос.
  5. Не разработчик, а сам сервлет или web-контейнер управляют жизненным циклом сервлета, то есть тем, как долго экземпляр сервлета существует в JVM и обрабатывает запросы. Когда контейнер сервлета намеревается исключить сервлет из обслуживания, он вызывает метод destroy() сервлета, в котором сервлет может освободить любые ресурсы, например соединение с БД.

Создадим теперь в пакете ru.topcode.testserv класс FirstServlet. Этот класс расширяет класс HttpServlet и содержит два метода: doGet() и doPost().

package ru.topcode.testserv;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 *
 * @author dmitrii.leontiev
 */
public class FirstServlet extends HttpServlet {
 
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("Cp1251");
 
        // Устанавливаем MIME
        response.setContentType("text/html;charset=Windows-1251");
 
        PrintWriter out = response.getWriter();
        out.println("<html><head>");
        out.println("<title>Мой первый сервлет</title></head><body>");
        out.println("<h2>Введите информацию о себе:</h2>");
        out.println("<form method=\"post\" action=\"" + request.getContextPath() + "/firstservlet\">");
        out.println("<table border=\"0\"><tr><td align=\"top\">");
        out.println("Имя:</td> <td valign=\"top\">");
        out.println("<input type=\"text\" name=\"firstname\" size=\"20\">");
        out.println("</td></tr><tr><td valign=\"top\">");
        out.println("Фамилия: </td> <td valign=\"top\">");
        out.println("<input type=\"text\" name=\"lastname\" size=\"20\">");
        out.println("</td></tr><tr><td valign=\"top\">");
        out.println("E-Mail: </td> <td valign=\"top\">");
        out.println("<input type=\"text\" name=\"email\" size=\"20\">");
        out.println("</td></tr><tr><td valign=\"top\">");
 
        out.println("<input type=\"submit\" value=\"Отправить\"></td></tr>");
        out.println("</table></form>");
        out.println("</body></html>");
    }
 
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("Cp1251");
        Enumeration paramNames = request.getParameterNames();
        String parName;
 
        boolean emptyEnum = false;
        if (!paramNames.hasMoreElements()) {
            emptyEnum = true;
        }
 
        response.setContentType("text/html;charset=Windows-1251");
        PrintWriter out = response.getWriter();
 
        out.println("<html><head>");
        out.println("<title>Отправленные параметры</title></head><body>");
 
        if (emptyEnum) {
            out.println("<h2>Запрос не содержит параметров</h2>");
        } else {
            out.println("<h2>Это значения переданных параметров:</h2>");
        }
 
        while (paramNames.hasMoreElements()) {
            parName = (String) paramNames.nextElement();
            out.println("<strong>" + parName + "</strong> : " + request.getParameter(parName));
            out.println("<br />");
        }
        out.println("</body></html>");
    }
}

Как видно из примера, методы doGet() и doPost() могут вызывать исключения ServletException и IOException. Сервлет может вызвать IOException, поскольку вызов метода response.getWriter() (как и метода PrintWriter.close()) может вызвать это исключение. Методы doGet() и doPost() могут вызывать исключение ServletException, чтобы сигнализировать о возникновении ошибки в ходе обработки запроса.

Итак, сервлет написан, осталось теперь проверить как он работает.

Для того, чтобы запустить сервлет, нам нужно отредактировать дескриптор развертывания. Дескриптор развертывание – очень важная часть web-приложения. В нем, в кратком виде, содержатся требования web-приложения. Его можно прочитать в большинстве XML-редакторов. Web.xml файл – это место, где вы:

  • Регистрируете и создаете отображение URL на ваши сервлеты;
  • Регистрируете и задаете любые фильтры и слушатели приложения;
  • Задаете начальные параметры контекста в виде пар имя/значение;
  • Конфигурируете страницы ошибок;
  • Указываете начальные файлы приложения;
  • Задаете время простоя сеанса (тайм-аут);
  • Задаете настройки безопасности, управляющие тем, кто к каким web-компонентам может обращаться.

И это только часть тех настроек, которые можно задать в web.xml.

В нашем приложении web.xml находится в Web Pages/WEB-INF/. Откройте его в NetBeans и перейдите в режим правки XML.

Подробней о дескрипторе развертывания я расскажу в следующих постах, а сейчас просто добавьте внутрь тега web-app следующие строки:

<servlet>
    <servlet-name>FirstServlet</servlet-name>
    <servlet-class>ru.topcode.testserv.FirstServlet</servlet-class>
</servlet>
 
<servlet-mapping>
    <servlet-name>FirstServlet</servlet-name>
    <url-pattern>/firstservlet</url-pattern>
</servlet-mapping>

Теперь нажмите F6. Ваше приложение должно запуститься, а на экране вы увидите все тот же “Hello World!”. Добавьте в URL firstservlet так, чтобы получился следующий адрес: http://localhost:8084/test-servlet/firstservlet и перейдите по нему.

Если вы все выполняли по инструкции, то на вашем экране должно быть примерно следующее:

firstservlet

Теперь заполните текстовые поля и нажмите “Отправить”. Если вы все сделали правильно, то должны наблюдать следующий результат:

Первый сервлет на Java в работе

Вы создали и запустили ваш первый сервлет. С чем вас и поздравляю. В следующем посту мы научимся создавать JSP-страницы и добавлять их в web-приложение.