← Назад к вопросам

Что такое Servlet?

1.3 Junior🔥 191 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Servlet - основа веб-приложений на Java

Servlet - это Java класс, который обрабатывает HTTP запросы и генерирует HTTP ответы. Это фундамент веб-приложений на Java.

История и роль Servlet

Servlet появился в 1997 году как решение для создания динамических веб-приложений (в то время была только статика). Сегодня Servlet - это стандарт Java EE (Jakarta EE), на котором построены все современные web frameworks: Spring, Jakarta Faces, Apache Struts и другие.

Что такое Servlet на самом деле

Servlet - это interface из Java EE спецификации:

public interface Servlet {
    void init(ServletConfig config) throws ServletException;
    void service(ServletRequest request, ServletResponse response) throws ServletException, IOException;
    void destroy();
    ServletConfig getServletConfig();
    String getServletInfo();
}

Обычно extends HttpServlet:

public abstract class HttpServlet extends GenericServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { }
    
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { }
    
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { }
    
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { }
}

Жизненный цикл Servlet

public class UserServlet extends HttpServlet {
    
    // 1. Инициализация - вызывается один раз при загрузке
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        System.out.println("Servlet инициализирован");
        // Здесь можно загрузить ресурсы, подключиться к БД
    }
    
    // 2. Обработка запроса - вызывается для каждого HTTP запроса
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        System.out.println("GET запрос получен");
        
        // Читаем параметры из запроса
        String userId = request.getParameter("id");
        
        // Выполняем логику
        String userName = getUserName(userId);
        
        // Отправляем ответ
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println("<html><body>");
        response.getWriter().println("<h1>User: " + userName + "</h1>");
        response.getWriter().println("</body></html>");
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        System.out.println("POST запрос получен");
        
        // Читаем параметры POST
        String name = request.getParameter("name");
        String email = request.getParameter("email");
        
        // Сохраняем пользователя
        saveUser(name, email);
        
        // Перенаправляем
        response.sendRedirect("/users");
    }
    
    // 3. Очистка - вызывается один раз при выгрузке Servlet'а
    @Override
    public void destroy() {
        System.out.println("Servlet завершает работу");
        // Закрываем ресурсы, соединения с БД
    }
    
    private String getUserName(String userId) {
        // Логика получения имени из БД
        return "John Doe";
    }
    
    private void saveUser(String name, String email) {
        // Логика сохранения в БД
    }
}

Архитектура Servlet контейнера

Client (браузер)
    |  HTTP запрос
    v
Web Server (Apache, Nginx)
    |  Переда на Java приложение
    v
Servlet Container (Tomcat, Jetty, JBoss)
    |  Маршрутизирует на нужный Servlet
    v
Servlet (ваш класс)
    |  Обрабатывает запрос
    v
Servlet Container
    |  Возвращает ответ
    v
Web Server
    |  HTTP ответ
    v
Client (браузер) получает ответ

Практический пример: REST API с Servlet

@WebServlet("/api/users/*")
public class UserAPIServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        // Распарсиваем URL: /api/users/123
        String pathInfo = request.getPathInfo();  // Получаем /123
        Long userId = extractUserId(pathInfo);
        
        // Получаем пользователя из БД
        User user = userService.findById(userId);
        
        if (user == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.getWriter().write("{\"error\":\"User not found\"}");
            return;
        }
        
        // JSON ответ
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        String json = objectMapper.writeValueAsString(user);
        response.getWriter().write(json);
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        // Читаем JSON из body
        String body = readRequestBody(request);
        User newUser = objectMapper.readValue(body, User.class);
        
        // Сохраняем
        User savedUser = userService.save(newUser);
        
        // Возвращаем созданного пользователя
        response.setStatus(HttpServletResponse.SC_CREATED);
        response.setContentType("application/json");
        response.setHeader("Location", "/api/users/" + savedUser.getId());
        response.getWriter().write(objectMapper.writeValueAsString(savedUser));
    }
    
    @Override
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        String pathInfo = request.getPathInfo();
        Long userId = extractUserId(pathInfo);
        
        userService.deleteById(userId);
        
        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
    }
    
    private Long extractUserId(String pathInfo) {
        // /123 -> 123
        return Long.parseLong(pathInfo.substring(1));
    }
    
    private String readRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        return sb.toString();
    }
}

Servlet конфигурация

Через @WebServlet аннотацию (Servlet 3.0+)

@WebServlet("mapping/path")
public class MyServlet extends HttpServlet { }

@WebServlet("/users")  // GET /users
public class UsersServlet extends HttpServlet { }

@WebServlet("/api/users/*")  // GET /api/users/*, /api/users/123
public class UserAPIServlet extends HttpServlet { }

Через web.xml (старый способ)

<web-app>
    <servlet>
        <servlet-name>userServlet</servlet-name>
        <servlet-class>com.example.UserServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>userServlet</servlet-name>
        <url-pattern>/users</url-pattern>
    </servlet-mapping>
</web-app>

ServletRequest и ServletResponse

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
    
    // HttpServletRequest - получение данных от клиента
    String param = request.getParameter("key");           // Параметр
    String header = request.getHeader("User-Agent");      // Заголовок
    String method = request.getMethod();                  // GET, POST, PUT...
    String path = request.getPathInfo();                  // Путь
    int port = request.getServerPort();                   // Порт сервера
    HttpSession session = request.getSession();           // Сессия
    Cookie[] cookies = request.getCookies();              // Cookies
    
    // HttpServletResponse - отправка ответа клиенту
    response.setStatus(200);                              // HTTP статус
    response.setContentType("text/html;charset=UTF-8");  // Content-Type
    response.setHeader("Custom-Header", "value");         // Заголовок
    response.addCookie(new Cookie("name", "value"));      // Cookie
    
    PrintWriter writer = response.getWriter();
    writer.println("Ответ");
}

Сессии в Servlet

public void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
    
    // Получаем или создаем сессию
    HttpSession session = request.getSession(true);
    
    // Сохраняем данные в сессию
    session.setAttribute("userId", 123);
    session.setAttribute("username", "john_doe");
    
    // Читаем из сессии
    Object userId = session.getAttribute("userId");
    
    // Удаляем сессию
    session.invalidate();
}

Filter и Servlet

Filer'ы перехватывают запросы ДО Servlet'а:

@WebFilter("/*")  // Все запросы
public class LoggingFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        
        System.out.println("Запрос до Servlet: " + request);
        
        // Передаем дальше
        chain.doFilter(request, response);
        
        System.out.println("Ответ после Servlet");
    }
}

Современный подход: Spring Framework

В современных приложениях Servlet'ы используются опосредованно через Spring:

// Spring под капотом использует DispatcherServlet
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
}

// Spring наследует от HttpServlet и обрабатывает запросы
// @Controller методы вызываются из Servlet'а

Когда использовать Servlet напрямую

  1. Низкоуровневая обработка - HTTP запросов
  2. Специфичные requirements - file upload, streaming
  3. Legacycode - старые приложения
  4. Performance critical - когда нужна полная контроль

Обычно используешь Spring, но понимание Servlet'ов - обязательно для хорошего Java разработчика.

Резюме

  • Servlet - основной компонент Java веб-приложений
  • Жизненный цикл - init → doGet/doPost/... → destroy
  • Контейнер - Tomcat, Jetty управляют Servlet'ами
  • Современный подход - Spring скрывает Servlet'ы, но они есть под капотом
  • Обязательно знать - даже если не пишешь их напрямую