В чем разница между сервлетами и контроллерами в Spring
Что проверяют
Понимаете ли вы, что это не альтернативы, а уровни: Spring MVC построен поверх сервлета.
Как отвечать
Сервлет это низкоуровневая спецификация Java (сейчас Jakarta). Класс наследует HttpServlet, переопределяет doGet и doPost, работает напрямую с HttpServletRequest и HttpServletResponse: сам разбирает параметры, сам пишет ответ в поток, сам сопоставляет адреса.
Контроллер Spring это класс с @Controller или @RestController, где методы размечены @GetMapping, @PostMapping и получают уже разобранные параметры.
Ключевое, что стоит сказать: Spring MVC работает поверх сервлетов. В приложении есть один единственный сервлет, DispatcherServlet, который принимает все запросы и раздаёт их методам контроллеров. Это шаблон «единая точка входа». То есть контроллер не заменяет сервлет, он живёт внутри него.
Что берёт на себя Spring вместо ручной работы:
- сопоставление адреса и метода по аннотациям вместо конфигурации;
- привязка параметров:
@PathVariable,@RequestParam,@RequestBodyс автоматическим разбором JSON через конвертеры сообщений; - валидация через
@Valid; - обработка исключений централизованно в
@ControllerAdviceвместоtryв каждом методе; - согласование форматов: тот же метод отдаёт JSON или XML по заголовку клиента;
- тестируемость: контроллер это обычный класс, его методы вызываются напрямую в тесте, а
MockMvcпроверяет весь слой без поднятия сервера.
Полезное дополнение про современность: Spring WebFlux уходит от сервлетов вовсе. Там реактивный стек поверх Netty, и модель «поток на запрос» заменена на неблокирующую.
Где спотыкаются
Считают сервлеты и контроллеры взаимоисключающими подходами.
Не знают про DispatcherServlet и единую точку входа.
Работают с HttpServletResponse внутри контроллера там, где хватило бы возврата объекта.
Ловят исключения в каждом методе вместо общего обработчика.