› Архитектура Spring MVC (DispatcherServlet)
Spring MVC построен на паттерне Front Controller. Все входящие HTTP-запросы сначала попадают в один главный сервлет — DispatcherServlet.
Жизненный цикл обработки HTTP-запроса:
- Запрос: Клиент отправляет HTTP-запрос (например,
GET /users/1). Запрос перехватываетсяDispatcherServlet. - Маршрутизация (HandlerMapping):
DispatcherServletобращается кHandlerMapping. Тот ищет в реестре контроллеров метод, помеченный аннотацией@GetMapping("/users/{id}"), и возвращаетHandlerExecutionChain(сам метод контроллера + список перехватчиков/интерцепторов). - Адаптер (HandlerAdapter):
DispatcherServletпередает запрос вHandlerAdapter. Адаптер берет сырой HTTP-запрос, извлекает из него параметры (Path Variables, Query Params, Body), конвертирует их в Java-объекты (например, через Jackson) и вызывает твой метод в контроллере. - Выполнение: Твой метод отрабатывает (идет в Service, БД) и возвращает результат (объект или DTO).
- Конвертация ответа (HttpMessageConverter): Если метод помечен
@ResponseBody(или класс помечен@RestController),DispatcherServletпередает возвращенный Java-объект вHttpMessageConverter(обычноMappingJackson2HttpMessageConverter), который сериализует объект в JSON и записывает в тело HTTP-ответа.
› REST (Representational State Transfer)
REST — это архитектурный стиль для проектирования сетевых API.
Основные принципы RESTful API:
- Client-Server: Разделение интерфейса (фронтенд) и хранения данных (бэкенд).
- Stateless (Без состояния): Сервер не хранит состояние сессии клиента между запросами. Каждый запрос должен содержать всю информацию, необходимую для его выполнения (например, JWT-токен).
- Cacheable: Ответы сервера должны явно указывать, можно ли их кэшировать.
- Uniform Interface (Единообразный интерфейс):
- Идентификация ресурсов через URI (существительные во множественном числе:
/users,/orders). - Манипуляция ресурсами через стандартные HTTP-методы.
- Идентификация ресурсов через URI (существительные во множественном числе:
HTTP-методы и их семантика:
GET— получение ресурса. Идемпотентный (повторный вызов не меняет состояние сервера) и Безопасный (не меняет данные).POST— создание нового ресурса. Не идемпотентный (два вызова создадут два ресурса).PUT— полное обновление ресурса (или создание, если его нет). Идемпотентный (повторный вызов оставит ресурс в том же состоянии).PATCH— частичное обновление ресурса. (Обычно не идемпотентный, зависит от реализации).DELETE— удаление ресурса. Идемпотентный.
› Основные аннотации Spring MVC
@Controllervs@RestController:@Controllerиспользуется для классического MVC (возвращает имя HTML-шаблона, например Thymeleaf, который рендерится на сервере).@RestController=@Controller+@ResponseBody. Все методы автоматически сериализуют возвращаемый объект в JSON/XML и пишут в тело ответа.
@RequestMapping(и его шорткаты@GetMapping,@PostMappingи т.д.) — маппинг URL на метод.- Извлечение данных из запроса:
@PathVariable— извлекает переменную из пути URL (/users/{id}).@RequestParam— извлекает параметры запроса (Query parameters:/users?role=admin).@RequestBody— десериализует тело HTTP-запроса (JSON) в Java-объект.@RequestHeader— извлекает HTTP-заголовки.
› Валидация (Bean Validation / Hibernate Validator)
В Spring Boot валидация подключается через стартер spring-boot-starter-validation.
Как работает:
- В DTO-классе (Data Transfer Object) поля помечаются аннотациями:
@NotNull,@NotBlank(для строк, проверяет что не null и не состоит только из пробелов),@Size(min=2, max=50),@Email,@Min,@Max. - В контроллере перед параметром
@RequestBodyставится аннотация@Valid(или@Validated). - Когда Spring десериализует JSON в объект, он прогоняет его через валидатор. Если есть ошибки, метод контроллера не вызывается, а Spring автоматически выбрасывает
MethodArgumentNotValidExceptionи возвращает клиенту HTTP статус400 Bad Request.
› Обработка исключений (Exception Handling)
Вместо того чтобы писать try-catch в каждом методе контроллера, в Spring используется глобальный перехватчик исключений (AOP-подход).
@ControllerAdvice/@RestControllerAdvice: Класс, помеченный этой аннотацией, перехватывает исключения, выброшенные из любого контроллера.@ExceptionHandler(MyCustomException.class): Метод внутри Advice-класса. Если где-то в приложении (в сервисе или контроллере) вылетитMyCustomException, Spring прервет выполнение и передаст управление в этот метод.- Зачем нужно: Позволяет централизованно формировать красивый и стандартизированный JSON-ответ с ошибкой (например, поля
timestamp,status,message,path) и правильным HTTP-статусом (через@ResponseStatus).