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
предназначен для вызова только один раз. Если экземпляр сервлета не существует, веб-контейнер:
- Загружает класс сервлета
- Создает экземпляр класса сервлета
- Инициализирует его, вызывая метод
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 .