Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Как работает Router в Java
Определение
Router в Java — это компонент, который маршрутизирует HTTP запросы на правильные обработчики (controllers) на основе URL пути, метода HTTP и других параметров.
Front Controller паттерн
В Spring используется Front Controller:
Клиент → HTTP запрос GET /api/users/123
↓
DispatcherServlet (главный entry point)
↓
HandlerMapping (найти подходящий handler)
↓
UserController.getById(123)
↓
HTTP ответ
RequestMapping аннотации
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping // GET /api/users
public List<User> getAll() {
return userService.findAll();
}
@GetMapping("/{id}") // GET /api/users/123
public User getById(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping // POST /api/users
public User create(@RequestBody User user) {
return userService.save(user);
}
@PutMapping("/{id}") // PUT /api/users/123
public User update(@PathVariable Long id, @RequestBody User user) {
return userService.update(id, user);
}
@DeleteMapping("/{id}") // DELETE /api/users/123
public void delete(@PathVariable Long id) {
userService.delete(id);
}
}
DispatcherServlet — сердце маршрутизации
Это main servlet, который обрабатывает ВСЕ запросы:
public class DispatcherServlet extends HttpServlet {
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
// 1. Получить HTTP метод и путь
String method = request.getMethod(); // GET, POST, ...
String path = request.getRequestURI(); // /api/users/123
// 2. Найти подходящий handler в карте
// Карта создаётся при старте приложения
HandlerExecutionChain handler = getHandler(request);
// Результат: UserController.getById
// 3. Извлечь path variables
// {id} = 123 (из /users/{id})
// 4. Вызвать метод контроллера
Object result = handler.getHandler().invoke(
userController,
123L // параметр id
);
// Результат: User object
// 5. Сериализовать в JSON
String json = objectMapper.writeValueAsString(result);
// 6. Вернуть ответ
response.setContentType("application/json");
response.getWriter().write(json);
}
}
RequestMappingHandlerMapping
Это компонент, который создаёт карту всех routes при старте приложения:
public class RequestMappingHandlerMapping {
// Spring сканирует все @RestController и @RequestMapping
// И создаёт эту карту:
private Map<RequestMappingInfo, HandlerMethod> mappingRegistry = new HashMap<>();
// После инициализации:
// GET /api/users → UserController.getAll()
// GET /api/users/{id} → UserController.getById(Long)
// POST /api/users → UserController.create(User)
// PUT /api/users/{id} → UserController.update(Long, User)
// DELETE /api/users/{id} → UserController.delete(Long)
// Когда приходит запрос
public HandlerExecutionChain getHandler(HttpServletRequest request) {
String method = request.getMethod();
String path = request.getRequestURI();
// Поиск по методу и пути
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : mappingRegistry.entrySet()) {
if (entry.getKey().matches(method, path)) {
return new HandlerExecutionChain(entry.getValue());
}
}
throw new 404 Not Found;
}
}
Path Variable Extraction
@GetMapping("/users/{userId}/orders/{orderId}")
public Order getOrder(
@PathVariable Long userId,
@PathVariable Long orderId
) {
return orderService.findByUserAndOrder(userId, orderId);
}
// Запрос: GET /users/123/orders/456
// DispatcherServlet делает:
// 1. Сравнивает путь: /users/123/orders/456 ~ /users/{userId}/orders/{orderId}
// 2. Извлекает: {userId} = 123, {orderId} = 456
// 3. Вызывает: getOrder(123L, 456L)
Route Priority (специфичность)
@RestController
public class ItemController {
// ✅ Более специфичный путь — приоритет выше
@GetMapping("/items/latest")
public Item getLatest() {
return itemService.getLatest();
}
// Менее специфичный путь — приоритет ниже
@GetMapping("/items/{id}")
public Item getById(@PathVariable Long id) {
return itemService.findById(id);
}
}
// Запрос: GET /items/latest
// Маршрутизируется в getLatest(), а не getById("latest")
ContentNegotiation — выбор формата
@RestController
public class ReportController {
@GetMapping("/report")
public Report getReport() {
return new Report(...);
}
}
// На основе Accept header выбирается формат:
// Accept: application/json → JSON
// Accept: application/xml → XML
// Accept: text/csv → CSV (если настроено)
RequestMapping параметры
@RestController
public class OrderController {
// По пути
@RequestMapping(path = "/orders", method = RequestMethod.GET)
public List<Order> getOrders() { ... }
// По параметрам запроса
@RequestMapping("/search")
@RequestParam("status") String status // ?status=pending
public List<Order> search() { ... }
// По headers
@RequestMapping("/export")
@RequestHeader("X-Format") String format // X-Format: csv
public String export() { ... }
// По content type
@RequestMapping(
path = "/data",
consumes = "application/json", // Принимает JSON
produces = "application/json" // Возвращает JSON
)
public Data handleData(@RequestBody Data data) { ... }
}
Обработка 404
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(NoHandlerFoundException e) {
// Если path не найден в маппинге
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse(
"Route not found: " + e.getRequestURL()
));
}
}
Как это работает под капотом
1. Приложение стартует
↓
2. Spring сканирует все @RestController и @RequestMapping
↓
3. RequestMappingHandlerMapping создаёт карту routes
↓
4. DispatcherServlet регистрируется в Tomcat
↓
5. Клиент отправляет HTTP запрос
↓
6. Tomcat → DispatcherServlet.doDispatch()
↓
7. Ищет matching route в карте (по методу и пути)
↓
8. Извлекает path variables и query parameters
↓
9. Вызывает соответствующий метод контроллера
↓
10. Сериализует результат в JSON (ContentNegotiation)
↓
11. Возвращает ответ клиенту
На собеседовании
"Router в Spring маршрутизирует HTTP запросы на правильные контроллеры.
Как работает:
- DispatcherServlet — главный entry point
- RequestMappingHandlerMapping — создаёт карту всех routes
- При запросе ищется matching route по методу HTTP и пути
- Извлекаются path variables и query parameters
- Вызывается метод контроллера
- Результат сериализуется (JSON/XML)
- Возвращается клиенту
Аннотации: @RequestMapping, @GetMapping, @PostMapping, @PathVariable, @RequestParam"