Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Запрос и ответ

Метод сервлета получает два объекта. 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/subscribe
HTTP/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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.