← Назад к вопросам
Какие знаешь аннотации контроллеров с дополнительным словом?
1.7 Middle🔥 181 комментариев
#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Аннотации контроллеров с дополнительным словом в Spring
В Spring Framework существует большое количество аннотаций для работы с контроллерами. Аннотации с дополнительным словом обычно предоставляют более специфичную функциональность. Давайте разберём самые важные из них.
Основные аннотации контроллеров
// @Controller — базовая аннотация для контроллеров (возвращает имя представления)
@Controller
public class UserViewController {
@GetMapping("/users")
public String showUsers(Model model) {
model.addAttribute("users", userService.getAll());
return "users/list"; // имя представления (HTML шаблон)
}
}
// @RestController — контроллер для REST API (возвращает JSON)
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@GetMapping
public List<UserDTO> getUsers() {
return userService.getAll();
}
}
// @RepositoryRestController — специализированный контроллер для работы с репозиториями
@RepositoryRestController
@RequestMapping("/api/custom-users")
public class CustomUserController {
@Autowired
private UserRepository userRepository;
@GetMapping("/special")
public ResponseEntity<List<User>> getSpecialUsers() {
return ResponseEntity.ok(userRepository.findSpecialUsers());
}
}
Аннотации для маршрутизации HTTP методов
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
// @GetMapping — обработка GET запросов (получение данных)
@GetMapping
public List<ProductDTO> getAllProducts() {
return productService.getAll();
}
@GetMapping("/{id}")
public ProductDTO getProduct(@PathVariable Long id) {
return productService.getById(id);
}
// @PostMapping — обработка POST запросов (создание данных)
@PostMapping
public ResponseEntity<ProductDTO> createProduct(
@RequestBody CreateProductRequest request
) {
Product product = productService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(new ProductDTO(product));
}
// @PutMapping — обработка PUT запросов (полное обновление)
@PutMapping("/{id}")
public ResponseEntity<ProductDTO> updateProduct(
@PathVariable Long id,
@RequestBody UpdateProductRequest request
) {
Product product = productService.update(id, request);
return ResponseEntity.ok(new ProductDTO(product));
}
// @PatchMapping — обработка PATCH запросов (частичное обновление)
@PatchMapping("/{id}/status")
public ResponseEntity<ProductDTO> updateStatus(
@PathVariable Long id,
@RequestBody UpdateStatusRequest request
) {
Product product = productService.updateStatus(id, request.getStatus());
return ResponseEntity.ok(new ProductDTO(product));
}
// @DeleteMapping — обработка DELETE запросов (удаление данных)
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
productService.delete(id);
return ResponseEntity.noContent().build();
}
}
Аннотации для параметров запроса
@RestController
@RequestMapping("/api/search")
public class SearchController {
@Autowired
private SearchService searchService;
// @RequestParam — для параметров строки запроса
@GetMapping("/users")
public List<UserDTO> searchUsers(
@RequestParam(name = "query", required = false) String query,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size
) {
return searchService.searchUsers(query, page, size);
}
// GET /api/search/users?query=john&page=1&size=50
// @PathVariable — для параметров пути URL
@GetMapping("/users/{id}/orders/{orderId}")
public OrderDTO getUserOrder(
@PathVariable Long id,
@PathVariable Long orderId
) {
return searchService.getUserOrder(id, orderId);
}
// GET /api/search/users/123/orders/456
// @RequestHeader — для заголовков HTTP
@GetMapping("/protected")
public ResponseEntity<DataDTO> getProtectedData(
@RequestHeader("Authorization") String authToken,
@RequestHeader(value = "X-API-Key", required = false) String apiKey
) {
return ResponseEntity.ok(searchService.getProtectedData(authToken, apiKey));
}
// @RequestBody — для тела запроса (обычно JSON)
@PostMapping("/advanced")
public List<ResultDTO> advancedSearch(
@RequestBody AdvancedSearchRequest request
) {
return searchService.advancedSearch(request);
}
// @RequestAttribute — для атрибутов запроса (установленных фильтрами/интерцепторами)
@GetMapping("/user-data")
public UserDTO getUserData(
@RequestAttribute("userId") Long userId
) {
return searchService.getUserData(userId);
}
// @CookieValue — для значений cookie
@GetMapping("/user-session")
public ResponseEntity<SessionDTO> getUserSession(
@CookieValue("JSESSIONID") String sessionId
) {
return ResponseEntity.ok(searchService.getSession(sessionId));
}
}
Аннотации для обработки исключений
// @ExceptionHandler — обработчик исключений в контроллере
@RestController
@RequestMapping("/api/items")
public class ItemController {
@Autowired
private ItemService itemService;
@GetMapping("/{id}")
public ItemDTO getItem(@PathVariable Long id) {
return itemService.getById(id);
}
@ExceptionHandler(ItemNotFoundException.class)
public ResponseEntity<ErrorResponse> handleItemNotFound(ItemNotFoundException e) {
ErrorResponse error = new ErrorResponse("Item not found", e.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResponse> handleIllegalArgument(IllegalArgumentException e) {
ErrorResponse error = new ErrorResponse("Invalid argument", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
}
// @ControllerAdvice — глобальный обработчик исключений
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<ErrorResponse> handleEntityNotFound(EntityNotFoundException e) {
ErrorResponse error = new ErrorResponse("Resource not found", e.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGlobalException(Exception e) {
ErrorResponse error = new ErrorResponse("Internal server error", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
// @RestControllerAdvice — комбинация @ControllerAdvice и @ResponseBody
@RestControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(ValidationException.class)
public ResponseEntity<ValidationErrorResponse> handleValidation(
ValidationException e,
HttpServletRequest request
) {
ValidationErrorResponse error = new ValidationErrorResponse(
"Validation failed",
e.getErrors(),
request.getRequestURI()
);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
}
Аннотации для кросс-доменных запросов
// @CrossOrigin — разрешение CORS для определённых источников
@RestController
@RequestMapping("/api/public")
public class PublicApiController {
@CrossOrigin(origins = "https://example.com", maxAge = 3600)
@GetMapping("/data")
public DataDTO getPublicData() {
return new DataDTO("public");
}
// Или на уровне класса
}
@RestController
@RequestMapping("/api/shared")
@CrossOrigin(origins = {"https://frontend.com", "https://mobile.com"}, maxAge = 7200)
public class SharedApiController {
@GetMapping("/info")
public InfoDTO getSharedInfo() {
return new InfoDTO();
}
}
Аннотации для валидации
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@PostMapping
public ResponseEntity<OrderDTO> createOrder(
@Valid @RequestBody CreateOrderRequest request // @Valid включает валидацию
) {
Order order = orderService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(new OrderDTO(order));
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ValidationErrorResponse> handleValidationException(
MethodArgumentNotValidException e
) {
List<String> errors = e.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getField() + ": " + error.getDefaultMessage())
.collect(Collectors.toList());
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ValidationErrorResponse("Validation failed", errors));
}
}
// Класс с валидацией
public class CreateOrderRequest {
@NotBlank(message = "Order number is required")
private String orderNumber;
@NotNull(message = "Amount is required")
@Min(value = 1, message = "Amount must be greater than 0")
private BigDecimal amount;
@Email(message = "Invalid email format")
private String customerEmail;
// getters and setters
}
Аннотации для документирования API (Swagger/OpenAPI)
@RestController
@RequestMapping("/api/products")
@Tag(name = "Products", description = "API для управления товарами")
public class ProductApiController {
@GetMapping("/{id}")
@Operation(summary = "Получить товар по ID", description = "Возвращает информацию о товаре")
@ApiResponse(responseCode = "200", description = "Товар найден")
@ApiResponse(responseCode = "404", description = "Товар не найден")
public ProductDTO getProduct(
@PathVariable @Parameter(description = "ID товара") Long id
) {
return productService.getById(id);
}
}
Практический пример полного контроллера
@RestController
@RequestMapping("/api/v1/articles")
@CrossOrigin(origins = "*", maxAge = 3600)
@Tag(name = "Articles", description = "API для работы со статьями")
public class ArticleController {
@Autowired
private ArticleService articleService;
@GetMapping
@Operation(summary = "Получить все статьи")
public List<ArticleDTO> getAllArticles(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
) {
return articleService.getAll(page, size);
}
@GetMapping("/{id}")
@Operation(summary = "Получить статью по ID")
public ArticleDTO getArticle(@PathVariable Long id) {
return articleService.getById(id);
}
@PostMapping
@Operation(summary = "Создать новую статью")
public ResponseEntity<ArticleDTO> createArticle(
@Valid @RequestBody CreateArticleRequest request
) {
Article article = articleService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(new ArticleDTO(article));
}
@PutMapping("/{id}")
@Operation(summary = "Обновить статью")
public ArticleDTO updateArticle(
@PathVariable Long id,
@Valid @RequestBody UpdateArticleRequest request
) {
return articleService.update(id, request);
}
@DeleteMapping("/{id}")
@Operation(summary = "Удалить статью")
public ResponseEntity<Void> deleteArticle(@PathVariable Long id) {
articleService.delete(id);
return ResponseEntity.noContent().build();
}
}
Заключение
Аннотации контроллеров в Spring предоставляют декларативный способ описания функциональности без написания лишнего кода. Знание этих аннотаций и их правильное использование позволяет разработчику создавать чистые, понятные и хорошо задокументированные REST API.