Запрос и ответ
Метод сервлета получает два объекта. HttpServletRequest — всё, что прислал клиент: адрес, параметры, заголовки, данные формы. HttpServletResponse — то, что уйдёт обратно: код ответа, заголовки и тело. Сделаем для блога поиск и форму подписки.
Параметры запроса
Параметр из строки запроса (?q=java) читают методом getParameter. Создайте файл src/main/java/com/example/blog/SearchServlet.java:
// src/main/java/com/example/blog/SearchServlet.java
package com.example.blog;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/search")
public class SearchServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/plain; charset=UTF-8");
PrintWriter out = response.getWriter();
String query = request.getParameter("q");
if (query == null || query.isBlank()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
out.println("Не указан параметр q");
return;
}
response.setHeader("X-Search-Query", query);
out.println("Ищем записи по запросу: " + query);
}
}Если параметра нет, getParameter вернёт null. Тогда сервлет ставит код 400 и сообщает об ошибке. Иначе он добавляет свой заголовок и печатает запрос.
curl -i "http://localhost:8080/blog/search?q=java"HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
X-Search-Query: java
Ищем записи по запросу: java
Без параметра (curl -i http://localhost:8080/blog/search) придёт HTTP/1.1 400 Bad Request и текст Не указан параметр q.
Данные формы и перенаправление
Поля HTML-формы, отправленной методом POST, читаются тем же getParameter. После обработки формы принято перенаправить браузер на другую страницу:
// src/main/java/com/example/blog/SubscribeServlet.java
package com.example.blog;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/subscribe")
public class SubscribeServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String email = request.getParameter("email");
System.out.println("Новый подписчик: " + email);
response.sendRedirect(request.getContextPath() + "/hello");
}
}getContextPath() возвращает /blog, поэтому адрес перенаправления не зависит от настроек сервера. Отправим форму через curl:
curl -i -d "email=anna@example.com" http://localhost:8080/blog/subscribeHTTP/1.1 302 Found
Location: http://localhost:8080/blog/hello
В логе сервера появится строка Новый подписчик: anna@example.com.
Полезные методы
| Метод | Что возвращает или делает |
|---|---|
request.getParameter("q") | Значение параметра или null |
request.getHeader("User-Agent") | Значение заголовка |
request.getMethod() | GET, POST и т. д. |
request.getRequestURI() | Путь, например /blog/search |
response.setStatus(404) | Код ответа |
response.setHeader(name, value) | Заголовок ответа |
response.sendRedirect(url) | Ответ 302 с адресом |
response.sendError(404) | Стандартная страница ошибки сервера |
Частая ошибка
Вызвать setContentType после getWriter(). Кодировка выбирается в момент получения PrintWriter, и поздний вызов уже ничего не меняет: сервер отправит Content-Type: text/plain; charset=ISO-8859-1, а русские буквы превратятся в ????. Сначала задавайте тип и кодировку, потом берите getWriter(). По той же причине в sendError не стоит передавать русский текст — страница ошибки сервера тоже выводится в ISO-8859-1.