Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# Что такое DispatcherServlet?
DispatcherServlet — это центральный компонент Spring Framework, который является Front Controller для всех входящих HTTP запросов. Это сердце Spring MVC.
Суть и назначение
DispatcherServlet перехватывает все HTTP запросы, поступающие в приложение, и маршрутизирует их к соответствующим обработчикам (контроллерам). Это паттерн Front Controller.
HTTP запрос → DispatcherServlet → Контроллер → Обработка → Ответ
Как это работает
1. Регистрация DispatcherServlet
В Spring Boot это происходит автоматически:
// Spring Boot конфигурация (автоматическая)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// DispatcherServlet уже зарегистрирован и слушает на /
}
}
// В традиционном Spring это было бы в web.xml
<!-- web.xml -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2. Жизненный цикл запроса
1. HTTP запрос приходит
↓
2. DispatcherServlet.doDispatch() — основной метод
↓
3. HandlerMapping определяет, какой контроллер обрабатывать
↓
4. HandlerAdapter находит нужный метод в контроллере
↓
5. Контроллер обрабатывает запрос (бизнес-логика)
↓
6. Возвращается ModelAndView (модель + представление)
↓
7. ViewResolver выбирает нужный View (JSP, HTML, JSON и т.д.)
↓
8. View рендерится и отправляется клиенту
Компоненты DispatcherServlet
HandlerMapping
Найти, какой контроллер должен обработать запрос:
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "John");
}
}
// GET /api/users/123
// HandlerMapping маршрутизирует это на UserController.getUser(123)
HandlerAdapter
Фактически вызвать метод контроллера с правильными параметрами:
// Контроллер
@PostMapping
public User createUser(
@RequestBody User user,
@RequestParam("notify") boolean notify
) {
return user;
}
// HandlerAdapter:
// 1. Десериализует @RequestBody из JSON
// 2. Извлекает @RequestParam из строки запроса
// 3. Вызывает метод с правильными аргументами
ViewResolver
Преобразовать имя View в реальное представление:
// Контроллер
@Controller
public class PageController {
@GetMapping("/users")
public String getUsers(Model model) {
model.addAttribute("users", List.of(...));
return "users-list"; // Имя шаблона
}
}
// ViewResolver (InternalResourceViewResolver)
// Преобразует "users-list" в "/WEB-INF/views/users-list.jsp"
// и загружает этот файл
Пример работы DispatcherServlet
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/data")
public ResponseEntity<Data> getData() {
// 1. DispatcherServlet получил GET /api/data
// 2. HandlerMapping нашёл этот метод
// 3. HandlerAdapter вызвал метод
// 4. Метод вернул ResponseEntity
// 5. DispatcherServlet сериализовал объект в JSON
// 6. Отправил ответ 200 OK с JSON телом
return ResponseEntity.ok(new Data("value"));
}
@PostMapping("/data")
public ResponseEntity<Data> createData(@RequestBody Data data) {
// 1. DispatcherServlet получил POST /api/data с JSON телом
// 2. HandlerMapping нашёл этот метод
// 3. HandlerAdapter десериализовал JSON в объект Data
// 4. Вызвал метод с этим объектом
// 5. Метод вернул ResponseEntity
// 6. DispatcherServlet сериализовал ответ в JSON
return ResponseEntity.status(201).body(data);
}
}
Конфигурация DispatcherServlet
// Кастомная конфигурация
@Configuration
public class DispatcherConfig {
@Bean
public DispatcherServlet dispatcherServlet(ApplicationContext ac) {
DispatcherServlet servlet = new DispatcherServlet(ac);
servlet.setThrowExceptionIfNoHandlerFound(true);
return servlet;
}
}
// Или через application.properties
spring.mvc.throw-exception-if-no-handler-found=true
spring.web.resources.add-mappings=false
Фильтры и Interceptors
DispatcherServlet работает с компонентами, которые перехватывают запросы:
// Filter (выполняется ПЕРЕД DispatcherServlet)
@Component
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Request before DispatcherServlet");
chain.doFilter(request, response);
System.out.println("Response after DispatcherServlet");
}
}
// Interceptor (выполняется ВНУТРИ DispatcherServlet)
@Component
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
System.out.println("Before handler");
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler, ModelAndView modelAndView) {
System.out.println("After handler");
}
}
// Порядок выполнения:
// 1. Filter.doFilter()
// 2. DispatcherServlet.doDispatch()
// 3. Interceptor.preHandle()
// 4. Handler (контроллер)
// 5. Interceptor.postHandle()
Практическое значение
✅ Centralized Request Handling — один вход для всех запросов ✅ Routing — автоматическая маршрутизация на контроллеры ✅ Binding — привязка параметров из запроса ✅ Exception Handling — централизованная обработка ошибок ✅ View Resolution — выбор нужного формата ответа (JSON, HTML) ✅ Interceptors — перехват и обработка на разных этапах
Отладка
# Логирование DispatcherServlet
logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG
# Покажет маршруты
logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=DEBUG
# Покажет исключения
logging.level.org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver=DEBUG
DispatcherServlet — это ключевой компонент Spring MVC, который автоматизирует маршрутизацию, привязку параметров и обработку ответов, позволяя разработчику сосредоточиться на бизнес-логике в контроллерах.