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

Есть ли Servlet в Spring

2.2 Middle🔥 151 комментариев
#Spring Framework

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

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

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

# Servlet в Spring

Да, Spring построен на основе Servlet, хотя в повседневной работе разработчики редко работают с Servlet напрямую.

Архитектура: Servlet как фундамент

Spring Web (Spring MVC) работает на базе Java Servlet API:

HTTP запрос
     ↓
Servlet Container (Tomcat, Jetty)
     ↓
DispatcherServlet (Spring)
     ↓
Controllers → Services → Repositories
     ↓
HTTP ответ

DispatcherServlet - фронт-контроллер Spring

// Spring автоматически регистрирует этот Servlet
public class DispatcherServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Маршрутизация запроса к контроллерам
        // Обработка исключений
        // Сериализация ответа
    }
}

Kогда вы создаёте @Controller с @GetMapping, Spring под капотом использует DispatcherServlet для обработки HTTP запросов.

Как это работает в Spring Boot

In Spring Boot конфигурация Servlet автоматична:

// application.properties
server.servlet.context-path=/api  // Путь Servlet'а
server.port=8080                   // Порт

// Java конфигурация (скрыта в Spring Boot)
@Configuration
public class ServletConfig {
    @Bean
    public DispatcherServlet dispatcherServlet(ApplicationContext context) {
        return new DispatcherServlet(context);
    }
}

Когда можно работать с Servlet напрямую

1. Кастомные фильтры

@Component
public class LoggingFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                     HttpServletResponse response,
                                     FilterChain filterChain)
            throws ServletException, IOException {
        System.out.println("Request: " + request.getRequestURI());
        filterChain.doFilter(request, response);
        System.out.println("Response status: " + response.getStatus());
    }
}

Фильтры работают ДО DispatcherServlet и могут модифицировать запрос/ответ.

2. Кастомные Servlet

@Component
public class CustomServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/plain");
        resp.getWriter().println("Custom Servlet");
    }
}

// Регистрация
@Configuration
public class ServletRegistration {
    @Bean
    public ServletRegistrationBean<CustomServlet> customServlet() {
        ServletRegistrationBean<CustomServlet> bean =
            new ServletRegistrationBean<>(new CustomServlet(), "/custom/*");
        return bean;
    }
}

Используется редко, когда нужна специфическая обработка на низком уровне.

3. Доступ к HttpServletRequest/Response в контроллере

@RestController
@RequestMapping("/api/users")
public class UserController {
    // Spring внедрит HttpServletRequest из Servlet API
    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(
            @PathVariable Long id,
            HttpServletRequest request,  // Servlet API
            HttpServletResponse response) {  // Servlet API
        
        String userAgent = request.getHeader("User-Agent");
        String sessionId = request.getSession().getId();
        
        response.setHeader("X-Custom-Header", "value");
        
        return ResponseEntity.ok(new User(id, "John"));
    }
}

Servlet контекст в Spring

@Component
public class ServletContextHelper {
    @Autowired
    private ServletContext servletContext;  // Доступ к контексту
    
    public void logServletInfo() {
        System.out.println("Server info: " + servletContext.getServerInfo());
        System.out.println("Context path: " + servletContext.getContextPath());
    }
}

Spring WebFlux - альтернатива без Servlet

Приемущественно для микросервисов и высоконагруженных систем:

// Spring WebFlux (основан на Netty, НЕ Servlet)
@RestController
@RequestMapping("/api/users")
public class UserHandler {
    @GetMapping("/{id}")
    public Mono<User> getUser(@PathVariable Long id) {
        return userService.getUserAsync(id);
    }
}

Условия использования:

  • Много одновременных подключений (10k+)
  • Non-blocking операции (асинхронный код)
  • Микросервисная архитектура

Сравнение

АспектSpring MVC (Servlet)Spring WebFlux (Async)
ОсноваHttpServletNetty, non-blocking
МодельСинхроннаяАсинхронная (Mono/Flux)
Потоки1 поток = 1 запросНесколько потоков на множество запросов
ЗависимостиПолно (JPA, Template Engines)Ограничено (только reactive)
СложностьПростая, привычнаяВыше, нужна reactive логика
Production примеры95% Java приложенийNetflix, Uber (высоконагруженные)

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

public class DispatcherServlet extends HttpServlet {
    // 1. init() - один раз при запуске
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        // Инициализация Spring контекста
    }
    
    // 2. service() - для каждого запроса
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) {
        // Обработка HTTP запроса
        super.service(req, res);
    }
    
    // 3. destroy() - при остановке
    @Override
    public void destroy() {
        // Очистка ресурсов
    }
}

Вывод

  1. Servlet — это базис Spring Web — DispatcherServlet наследует HttpServlet
  2. Обычно не используешь напрямую — Spring скрывает сложность за абстракциями
  3. Доступен когда нужен — фильтры, кастомные сервлеты, прямой доступ к HttpServletRequest
  4. Есть альтернатива — Spring WebFlux для асинхронных систем
  5. Знание Servlet важно для понимания того, как работает Spring под капотом

То есть: Spring на Servlet'ах, но ты кодишь на более высокоуровневых абстракциях (@Controller, @Service). Это хороший пример дизайна — скрывать сложность для удобства разработчика.

Есть ли Servlet в Spring | PrepBro