← Назад к вопросам
Что такое HTTP-статус 405?
2.0 Middle🔥 111 комментариев
#SOLID и паттерны проектирования#Spring Boot и Spring Data
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
HTTP статус 405: Method Not Allowed
405 Method Not Allowed — это HTTP статус код, который указывает, что метод запроса не поддерживается для данного ресурса. Другими словами, сервер знает о ресурсе, но операция (HTTP метод), которую пытается выполнить клиент, не разрешена.
Основное определение
Когда клиент отправляет запрос с HTTP методом (GET, POST, PUT, DELETE и т.д.), сервер проверяет:
- Существует ли ресурс? — если нет, возвращает 404 Not Found
- Поддерживает ли ресурс этот метод? — если нет, возвращает 405 Method Not Allowed
- Авторизован ли пользователь? — если нет, возвращает 403 Forbidden или 401 Unauthorized
Примеры из реальной жизни
Пример 1: неправильный метод для ресурса
# Правильно: получить список пользователей
GET /api/v1/users
# Ответ: 200 OK
# НЕПРАВИЛЬНО: отправить список пользователей (не создавать одного)
GET /api/v1/users
# Нужно использовать POST для создания
POST /api/v1/users
# Ответ: 200 OK
# ОШИБКА: пытаться обновить список
PUT /api/v1/users
# Ответ: 405 Method Not Allowed
# (нужно обновлять конкретного пользователя: PUT /api/v1/users/123)
Пример 2: ресурс только для чтения
# Правильно: прочитать профиль
GET /api/v1/users/123/profile
# Ответ: 200 OK
# ОШИБКА: попытка обновить через неправильный метод
GET /api/v1/users/123/profile (с Body)
# GET не должен иметь body
# Ответ: 405 Method Not Allowed
# Правильно: обновить профиль
PATCH /api/v1/users/123/profile
# Ответ: 200 OK
Как это выглядит в Spring Boot
Проблема: endpoint поддерживает только POST
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@PostMapping("/register")
public ResponseEntity<UserDTO> register(@RequestBody RegisterRequest request) {
// Поддерживает только POST
User user = userService.registerUser(request);
return ResponseEntity.status(201).body(UserMapper.toDTO(user));
}
}
// Что происходит:
// POST /api/v1/users/register → 200 OK
// GET /api/v1/users/register → 405 Method Not Allowed
// PUT /api/v1/users/register → 405 Method Not Allowed
// DELETE /api/v1/users/register → 405 Method Not Allowed
Правильная реализация CRUD операций
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
private final UserService userService;
// CREATE: POST создаёт новый ресурс
@PostMapping
public ResponseEntity<UserDTO> createUser(@RequestBody CreateUserRequest request) {
User user = userService.createUser(request);
return ResponseEntity.status(201).body(UserMapper.toDTO(user));
}
// READ: GET получает ресурс
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
User user = userService.findById(id)
.orElseThrow(() -> new UserNotFoundException());
return ResponseEntity.ok(UserMapper.toDTO(user));
}
// UPDATE: PUT или PATCH обновляют ресурс
@PutMapping("/{id}")
public ResponseEntity<UserDTO> updateUser(
@PathVariable Long id,
@RequestBody UpdateUserRequest request) {
User user = userService.updateUser(id, request);
return ResponseEntity.ok(UserMapper.toDTO(user));
}
// DELETE: удаляет ресурс
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
// НЕПОДДЕРЖИВАЕМЫЕ методы вернут 405 Method Not Allowed
// PATCH /api/v1/users/123 → 405 (если не определён @PatchMapping)
// HEAD /api/v1/users/123 → 405
// OPTIONS /api/v1/users/123 → 405 (если явно не реализован)
}
405 vs другие статусы
@RestController
@RequestMapping("/api/v1/protected")
public class ProtectedController {
@GetMapping
public ResponseEntity<String> publicGet() {
return ResponseEntity.ok("Public data");
}
@PostMapping
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<String> adminOnlyPost() {
return ResponseEntity.ok("Admin action");
}
}
// Сценарии ответов:
// 1. Метод существует и разрешён
GET /api/v1/protected
Ответ: 200 OK
// 2. Ресурс не существует
GET /api/v1/nonexistent
Ответ: 404 Not Found
// 3. Метод не существует для ресурса
DELETE /api/v1/protected
Ответ: 405 Method Not Allowed
// 4. Метод существует, но пользователь не авторизован
POST /api/v1/protected (без прав ADMIN)
Ответ: 403 Forbidden
// или
Ответ: 401 Unauthorized (если вообще не аутентифицирован)
// 5. Синтаксическая ошибка в запросе
GET /api/v1/protected?invalid=query&
Ответ: 400 Bad Request
Обработка 405 в Spring Boot
По умолчанию (автоматическая обработка)
@RestController
@RequestMapping("/api/v1/items")
public class ItemController {
@GetMapping
public ResponseEntity<List<ItemDTO>> getAll() {
return ResponseEntity.ok(itemService.getAll());
}
// Если клиент отправит: POST /api/v1/items
// Spring автоматически вернёт 405 Method Not Allowed
// потому что нет @PostMapping
}
Пользовательская обработка ошибок
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseEntity<ErrorResponse> handleMethodNotAllowed(
HttpRequestMethodNotSupportedException ex) {
ErrorResponse error = new ErrorResponse();
error.setStatus(405);
error.setMessage("Метод не поддерживается");
error.setMethod(ex.getMethod());
error.setAllowedMethods(ex.getSupportedHttpMethods());
return ResponseEntity
.status(HttpStatus.METHOD_NOT_ALLOWED)
.body(error);
}
}
public class ErrorResponse {
private int status;
private String message;
private String method;
private Set<HttpMethod> allowedMethods;
// getters и setters
}
// Ответ:
// {
// "status": 405,
// "message": "Метод не поддерживается",
// "method": "DELETE",
// "allowedMethods": ["GET", "POST", "PUT"]
// }
Правильное использование HTTP методов
// REST API Best Practices
// 1. COLLECTION OPERATIONS (на коллекцию ресурсов)
GET /api/v1/users // Получить список
POST /api/v1/users // Создать нового пользователя
PUT /api/v1/users // 405 - не обновляем коллекцию целиком
DELETE /api/v1/users // 405 - не удаляем коллекцию целиком
// 2. RESOURCE OPERATIONS (на конкретный ресурс)
GET /api/v1/users/123 // Получить пользователя
POST /api/v1/users/123 // 405 - пользователь уже создан
PUT /api/v1/users/123 // Обновить пользователя
DELETE /api/v1/users/123 // Удалить пользователя
PATCH /api/v1/users/123 // Частичное обновление
// 3. SUB-RESOURCE OPERATIONS
GET /api/v1/users/123/posts // Получить посты пользователя
POST /api/v1/users/123/posts // Создать пост для пользователя
GET /api/v1/users/123/posts/456 // Получить конкретный пост
DELETE /api/v1/users/123/posts/456 // Удалить конкретный пост
Примеры конфигурации в Spring
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// Можно настроить, какие методы игнорировать
configurer.setUseTrailingSlashMatch(true);
}
}
// Явно разрешить OPTIONS для CORS
@RestController
@RequestMapping("/api/v1/data")
public class DataController {
@GetMapping
public ResponseEntity<String> getData() {
return ResponseEntity.ok("data");
}
// OPTIONS обычно обрабатывается автоматически для CORS
// но можно переопределить:
@RequestMapping(method = RequestMethod.OPTIONS)
public ResponseEntity<?> handleOptions() {
return ResponseEntity
.ok()
.header("Allow", "GET, POST, OPTIONS")
.build();
}
}
Отладка 405 ошибок
// При получении 405, проверь:
// 1. Правильный ли HTTP метод?
GET vs POST vs PUT vs DELETE
// 2. Правильный ли URL?
/api/v1/users vs /api/v1/users/123
// 3. Определён ли endpoint для этого метода?
@GetMapping - определён
@PostMapping - не определён → 405
// 4. Правильные ли маршруты?
@RequestMapping("/api/v1/users")
@GetMapping - слушает /api/v1/users
// 5. Есть ли фильтры, которые блокируют метод?
// (например, SecurityFilterChain)
Заключение
405 Method Not Allowed — это правильный и информативный статус, который должен возвращаться, когда:
- Ресурс существует
- Но текущий HTTP метод не поддерживается
- Клиент должен использовать другой метод
Это часть REST API контракта, который помогает клиентам понять, как правильно взаимодействовать с API.