Изучаем JSP и Servlets. Часть 2. Основы сервлетов.

 

В этой статье в сжатой форме представлены основы строения сервлетов. Как правило, такого рода материала достаточно для того, чтобы получить представление о технологии Java Servlets.

 

Инструкции по настройке и установке Eclipse и Tomcat доступны здесь: Изучаем JSP и Servlets. Часть 1. Настройка Tomcat 7 + Eclipse + Java 7

 

Важно: я использую Tomcat, настроенный на использование порта 80, в то время как по умолчанию сервер слушает порт 8080. Поэтому у меня сервер доступен по адресу http://localhost/ (то есть используется предопределённый порт 80 протокола TCP, который можно не писать в адресе, это удобно), а для Tomcat с настройками по умолчанию адрес будет http://localhost:8080/. Имейте это в виду, когда будете проверять работу сервлетов, описанных в статье, поскольку я пишу адреса для своей конфигурации.

 

Задачи сервлетов

 

  • Чтение явных данных, отправленных клиентским приложением (данные форм, полей)
  • Чтение неявных данных, отправленных клиентским приложением (к примеру, заголовки запросов)
  • Построение результата обработки полученных данных.
  • Отправка явных данных обратно в клиент (к примеру, HTML данные, которые будут отображены на странице).
  • Отправка неявных данных обратно в клиент (коды статусов, заголовки ответа).

 

Таким образом, клиент обращается к сервлету при помощи HTTP-запросов, содержащих как данные форм, так и необходимые заголовки. Сервлет же генерирует ответ, содержащий данные из разных источников, используя для этого различные технологии. Сам ответ сервера представляет собой все тот же HTTP запрос.

 

Простейшие сервлеты

 

Рассмотрим сервлеты и их особенности на примерах.

 

Сервлет, генерирующий простой текст

 

Рассмотрим следующий пример:

 

package org.test.technerium.servlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
@WebServlet("/hello")
public class HelloWorld extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println("Hello World");
    }
}

 

Чтобы увидеть результат работы этого сервлета, откройте в браузере ссылку вида http://localhost/<Имя проекта>/hello. Там вы увидите следующее

 

 

Разберем данный выше код.

  • @Webservlet("/address") - аннотация, содержащая относительный путь к сервлету, подробнее написано ниже.
  • doGet - метод, отвечающий за обработку GET запросов. Для POST запросов используется метод doPost
  • HttpServletRequest - содержит всё то, что было получено от клиента
  • HttpServletResponse - используется для отправки данных к клиенту. Главным образом используется метод getWriter, чтобы получить PrintWriter, направляющий данные клиенту.

 

Итак, конкретный сервлет доступен по адресу http://<хост>/<Имя проекта>/<путь в аннотации>:

 

В нашем тестовом сервере хост - это просто localhost, имя проекта вы видите в списке проектов, а путь из аннотации - это относительный путь, указанный в аннотации @Webservlet.

 

Сервлет, генерирующий HTML код страницы

 

Результат работы предыдущего сервлета представляет собой всего лишь текст, не содержащий HTML тегов. Для того, чтобы полностью сформировать страницу, используя HTML, нам необходимо включить необходимые теги в тело ответа, а также задать заголовок ответа как "text/html".

 

Копируем предыдущий класс и добавляем изменения:

 

package org.test.technerium.servlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
@WebServlet("/hello_html")
public class HelloWorldHTML extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html"); //Задаем заголовок ответа
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE html>\n" + // формируем HTML страницы
                "<html>\n" +
                "<head><title>A Test Servlet</title></head>\n" +
                "<body bgcolor=\"#fdf5e6\">\n" +
                "<h1>Test</h1>\n" +
                "<p>Simple servlet for testing.</p>\n" +
                "</body></html>");
    }
}

 

Результат работы сервлета:

 

 

Использование вспомогательных классов

 

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

 

Принципы

 

  • Весь Java код находится одном месте. В Eclipe это src/<имя пакета>.
  • Помните про принципы ООП. Если какой-либо функционал используется много раз, вынесите его во вспомогательный класс.

Простой пример

Ниже приведен пример использования вспомогательного класса для генерации заголовка страницы из предыдущего примера. Естественно, генерация чистого HTML внутри реальных приложений - дело неблагодарное, лучше использовать JSP. Но мы стремимся увидеть принципы построения сервлетов и пока воспользуемся простейшим вариантом. Предполагается, что генерация заголовка страницы - это часто используемый функционал, который встречается во всех сервлетах нашего проекта, генерирующих HTML. Поэтому будет крайне полезным вынести эту логику за пределы сервлетов во вспомогательный класс:

 

package org.test.technerium.servlets.utilites;

public class Util {
    public static String headWithTitle(String title) {
        return("<!DOCTYPE html>\n" +
            "<html>\n" +
            "<head><title>" + title + "</title></head>\n");
    }
}

 

Использование этого класса в сервлете выглядит так:

 

package org.test.technerium.servlets.utilites;

import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
@WebServlet("/hello_html_util")
public class HelloWorldHTMLServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        String title = "Test Servlet with Utilities";
        out.println(Util.headWithTitle(title) +
            "<body bgcolor=\"#fdf5e6\">\n" +
            "<h1>" + title + "</h1>\n" +
            "<p>Simple servlet for testing.</p>\n" +
            "</body></html>");
    }
}

 

В браузере мы видим собранную страницу:

 

 

 

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

 

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

 

  • init - этот метод вызывается при первой загрузке сервлета. То есть не при каждом запросе.
  • service - вызывается в новом потоке для каждого запроса. Управляет методами doGet, doPost и пр. Не переопределяйте этот метод!
  • doGet, doPost, do... - вызываются при, соответственно, GET, POST и прочих запросах. Переопределяйте эти методы, чтобы обрабатывать запросы необходимого типа.
  • destroy - вызывается когда сервер удаляет объект сервлета. Не вызывается после каждого запроса.

 

Почему не стоит переопределять service

 

Этот метод не просто вызывает doGet, он автоматически обрабатывает HEAD, OPTIONS, TRACE запросы. Различные запросы вы можете обрабатывать, используя соответствующие методы (doPut, doTrace и тп.).

 


 

Исходники проекта Eclipse можно скачать по ссылке ниже

 

2ServletBasics.zip

Категория: 
Была ли статья полезна: 

Добавить комментарий

HTML

  • Разрешённые HTML-теги: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre> <p>
  • Строки и параграфы переносятся автоматически.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Поместите примеры вашего исходного кода в теги <code>...</code> or <source>...</source> и он будет красиво отформатирован.

Plain text

  • Поместите примеры вашего исходного кода в теги <code>...</code> or <source>...</source> и он будет красиво отформатирован.
  • Строки и параграфы переносятся автоматически.
  • Разрешённые HTML-теги: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <code> <source>
CAPTCHA
Пожалуйста, подтвердите, что вы человек.