middle
Как обрабатывать исключения в Spring MVC? Что такое @ExceptionHandler и @ControllerAdvice?
Spring MVC предоставляет механизм обработки исключений на разных уровнях. @ExceptionHandler обрабатывает исключения в одном контроллере. @ControllerAdvice – глобально для всех контроллеров.
Глобальный обработчик исключений
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(EntityNotFoundException ex) {
ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult().getFieldErrors().stream()
.map(e -> e.getField() + ": " + e.getDefaultMessage())
.collect(Collectors.toList());
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", "Ошибка валидации", errors);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<ErrorResponse> handleAccessDenied(AccessDeniedException ex) {
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ErrorResponse("ACCESS_DENIED", "Доступ запрещён"));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
log.error("Неожиданная ошибка", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("INTERNAL_ERROR", "Внутренняя ошибка сервера"));
}
}
public class ErrorResponse {
private String code;
private String message;
private List<String> details;
private LocalDateTime timestamp = LocalDateTime.now();
}
Ограничение области действия
Пример
@RestControllerAdvice(basePackages = "com.example.api")
public class ApiExceptionHandler { }
На собеседовании: покажите умение создать полноценный GlobalExceptionHandler с обработкой валидации, not found и fallback для всех исключений. Частая ошибка – не создавать обработчик
Exception.class(Spring вернёт stack trace, раскрывая внутреннюю структуру приложения).