Перейти к основному содержимому

Введение в сервлеты Java

· 5 мин. чтения

1. Обзор

В этой статье мы рассмотрим основной аспект веб-разработки на Java — сервлеты.

2. Сервлет и контейнер

Проще говоря, сервлет — это класс, который обрабатывает запросы, обрабатывает их и отвечает ответом.

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

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

3. Зависимости Maven

Чтобы добавить поддержку сервлетов в наше веб-приложение, файл javax . требуется зависимость servlet-api :

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>

Последнюю зависимость maven можно найти здесь .

Конечно, нам также нужно настроить контейнер сервлетов для развертывания нашего приложения; это хорошее место для начала развертывания WAR на Tomcat .

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

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

4.1. в этом()

Метод init предназначен для вызова только один раз. Если экземпляр сервлета не существует, веб-контейнер:

  1. Загружает класс сервлета
  2. Создает экземпляр класса сервлета
  3. Инициализирует его, вызывая метод init

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

public void init() throws ServletException {
// Initialization code like set up database etc....
}

4.2. оказание услуг()

Этот метод вызывается только после успешного завершения метода init() сервлета .

Контейнер вызывает метод service() для обработки запросов, поступающих от клиента, интерпретирует тип HTTP-запроса ( GET , POST , PUT , DELETE и т. д .) и вызывает методы doGet , doPost , doPut , doDelete и т. д. по мере необходимости.

public void service(ServletRequest request, ServletResponse response) 
throws ServletException, IOException {
// ...
}

4.3. разрушать()

Вызывается контейнером сервлетов для вывода сервлета из эксплуатации.

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

public void destroy() {
//
}

5. Пример сервлета

Пожалуйста, обратитесь к руководству по развертыванию приложения в Tomcat Root , чтобы изменить корень контекста с javax-servlets-1.0-SNAPSHOT на /

Add <Context path="/" docBase="javax-servlets-1.0-SNAPSHOT"></Context> в Host тег в $CATALINA_HOME\conf\server.xml

Давайте теперь настроим полный пример обработки информации с помощью формы.

Для начала давайте определим сервлет с сопоставлением /calculateServlet , который будет собирать информацию, отправленную формой POST, и возвращать результат с помощью RequestDispatcher :

@WebServlet(name = "FormServlet", urlPatterns = "/calculateServlet")
public class FormServlet extends HttpServlet {

@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

String height = request.getParameter("height");
String weight = request.getParameter("weight");

try {
double bmi = calculateBMI(
Double.parseDouble(weight),
Double.parseDouble(height));

request.setAttribute("bmi", bmi);
response.setHeader("Test", "Success");
response.setHeader("BMI", String.valueOf(bmi));

request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
} catch (Exception e) {
request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
}
}

private Double calculateBMI(Double weight, Double height) {
return weight / (height * height);
}
}

Как показано выше, классы, аннотированные @WebServlet, должны расширять класс javax.servlet.http.HttpServlet . Важно отметить, что аннотация @WebServlet доступна только начиная с Java EE 6.

Аннотация @WebServlet обрабатывается контейнером во время развертывания, и соответствующий сервлет становится доступным по указанным шаблонам URL. Стоит отметить, что, используя аннотацию для определения шаблонов URL, мы можем избежать использования дескриптора развертывания XML с именем web.xml для сопоставления нашего сервлета.

Если мы хотим отобразить сервлет без аннотаций, мы можем вместо этого использовать традиционный файл web.xml :

<web-app ...>

<servlet>
<servlet-name>FormServlet</servlet-name>
<servlet-class>com.root.FormServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FormServlet</servlet-name>
<url-pattern>/calculateServlet</url-pattern>
</servlet-mapping>

</web-app>

Далее давайте создадим базовую HTML- форму :

<form name="bmiForm" action="calculateServlet" method="POST">
<table>
<tr>
<td>Your Weight (kg) :</td>
<td><input type="text" name="weight"/></td>
</tr>
<tr>
<td>Your Height (m) :</td>
<td><input type="text" name="height"/></td>
</tr>
<th><input type="submit" value="Submit" name="find"/></th>
<th><input type="reset" value="Reset" name="reset" /></th>
</table>
<h2>${bmi}</h2>
</form>

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

public class FormServletLiveTest {

@Test
public void whenPostRequestUsingHttpClient_thenCorrect()
throws Exception {

HttpClient client = new DefaultHttpClient();
HttpPost method = new HttpPost(
"http://localhost:8080/calculateServlet");

List<BasicNameValuePair> nvps = new ArrayList<>();
nvps.add(new BasicNameValuePair("height", String.valueOf(2)));
nvps.add(new BasicNameValuePair("weight", String.valueOf(80)));

method.setEntity(new UrlEncodedFormEntity(nvps));
HttpResponse httpResponse = client.execute(method);

assertEquals("Success", httpResponse
.getHeaders("Test")[0].getValue());
assertEquals("20.0", httpResponse
.getHeaders("BMI")[0].getValue());
}
}

6. Сервлет, HttpServlet и JSP

Важно понимать, что технология Servlet не ограничивается протоколом HTTP.

На практике это почти всегда так, но Servlet — это общий интерфейс, а HttpServlet — это расширение этого интерфейса, добавляющее специфическую поддержку HTTP, такую как doGet и doPost и т. д.

Наконец, технология Servlet также является основным драйвером ряда других веб-технологий, таких как JSP — JavaServer Pages , Spring MVC и т. д.

7. Заключение

В этой быстрой статье мы представили основы сервлетов в веб-приложении Java.

Пример проекта можно загрузить и запустить как проект GitHub .