Sobes.tech
Middle+
84
questionbank

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

Ответ от нейросети

sobes.tech AI

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:

// Пример контроллера
package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/api/users") // Аннотация на уровне класса
public class UserController {

    @GetMapping("/hello") // Аннотация на уровне метода
    @ResponseBody // Указывает, что возвращаемое значение должно быть телом ответа
    public String sayHello() {
        return "Hello from user controller!";
    }
}

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