Middle+
46
questionbank

Как DispatcherServlet определяет, какой метод контроллера вызвать?

Получайте ответы на вопросы в реальном времени с Sobes Copilot
Ответ от нейросети sobes.tech

DispatcherServlet использует обработчики запросов (Handler Mappings) для определения контроллера и метода, который соответствует входящему HTTP-запросу.

Основные шаги:

  1. Получение запроса: DispatcherServlet получает HTTP-запрос.
  2. Поиск HandlerMapping: DispatcherServlet итерирует по сконфигурированным HandlerMapping'ам (например, RequestMappingHandlerMapping).
  3. Сопоставление запроса: Каждый HandlerMapping пытается сопоставить запрос с контроллером и методом, используя информацию из запроса (URL, HTTP-метод, заголовки и т.д.) и метаданные контроллера (например, аннотацию @RequestMapping).
  4. Определение обработчика: При успешном сопоставлении HandlerMapping возвращает объект HandlerExecutionChain, который содержит информацию о обработчике (обычно это метод контроллера) и списке перехватчиков (interceptors).
  5. Выполнение перехватчиков: DispatcherServlet выполняет пред-обработку с помощью перехватчиков (HandlerInterceptor.preHandle()).
  6. Вызов метода контроллера: Если перехватчики разрешают, DispatcherServlet вызывает соответствующий метод контроллера через HandlerAdapter (например, RequestMappingHandlerAdapter). HandlerAdapter отвечает за преобразование аргументов запроса в параметры метода контроллера и преобразование возвращаемого значения метода в ответ HTTP (например, ModelAndView, String, JSON и т.д.).
  7. Пост-обработка и рендеринг: После выполнения метода контроллера DispatcherServlet выполняет пост-обработку с помощью перехватчиков (HandlerInterceptor.postHandle()), определяет View (если необходимо) через ViewResolver, и рендерит ответ, выполняя HandlerInterceptor.afterCompletion() после отправки ответа.

Типичные HandlerMapping'и в Spring MVC:

  • RequestMappingHandlerMapping: Основан на аннотациях @RequestMapping, @GetMapping, @PostMapping и т.д. Наиболее часто используемый.
  • SimpleUrlHandlerMapping: Сопоставляет URL-пути напрямую с именами контроллеров или фабрик.
  • BeanNameUrlHandlerMapping: Сопоставляет URL-пути с именами бинов контроллеров.

Пример использования @RequestMapping:

java

В этом примере, при запросе /api/users/hello методом GET, RequestMappingHandlerMapping найдет UserController и вызовет метод sayHello().