Spring Boot: обработка глобальных исключений и корректное форматирование вывода
Spring Boot: обработка глобальных исключений и корректное форматирование вывода

Предисловие

Глобальная обработка исключений — очень важная функция в приложениях Spring Boot. Это может помочь нам перехватывать необработанные исключения, единообразно обрабатывать их и возвращать клиенту понятное сообщение об ошибке. В этой статье будет показано, как использовать Spring Boot для корректной обработки глобальных исключений, а также приведены некоторые практические примеры кода.

Текстовый контент

один. использовать@ControllerAdviceАннотация создает глобальный обработчик исключений

Весной MVCсередина,мы можем использовать@ControllerAdviceАннотация создает глобальный обработчик исключений.。Этот класс будет содержать методы для обработки различных исключений.,Эти методы можно использовать@ExceptionHandlerАннотировать с аннотациями。Вот простой пример:

Язык кода:java
копировать
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Внутренняя ошибка сервера");
    }
}

В этом примере,Мы создали файл под названиемGlobalExceptionHandlerКласс глобального обработчика исключений,и использовать@ControllerAdviceАннотировать с аннотациями。существоватьэтот класссередина,Мы определяем метод для обработки исключенийhandleException(),и использовать@ExceptionHandler(Exception.class)В аннотации указано, что метод используется для обработкиExceptionтип исключения。

2. Обработка определенных типов исключений

Помимо обработки всех типов исключений,Мы также можем создавать специализированные методы для обработки некоторых типичных исключений. Например,Мы можем создать метод для обработкиNullPointerExceptionаномальный:

Язык кода:java
копировать
@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> handleNullPointerException(NullPointerException e) {
    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Параметры запроса не могут быть пустыми");
}

3. Пользовательский класс исключений.

Для лучшей обработки исключений мы можем создавать собственные классы исключений и вызывать эти исключения там, где это необходимо. Вот простой пример пользовательского класса исключений:

Язык кода:java
копировать
public class CustomException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    public CustomException(String message) {
        super(message);
    }
}

4. Используйте собственные исключения в контроллерах.

В контроллере мы можем по мере необходимости генерировать собственные исключения. Например:

Язык кода:java
копировать
@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable Long id) {
        if (id == null || id <= 0) {
            throw new CustomException("Идентификатор пользователя должен быть положительным числом");
        }
        // ...другой логический код
    }
}

5. Обработка пользовательских исключений

Чтобы обрабатывать пользовательские исключения, нам нужно добавить соответствующие методы в глобальный класс обработчика исключений. Например:

Язык кода:java
копировать
@ExceptionHandler(CustomException.class)
public ResponseEntity<String> handleCustomException(CustomException e) {
    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}

6. Вернуть собственный ответ об ошибке

Чтобы клиент мог получать более понятную информацию об ошибках, мы можем создать собственный класс ответа на ошибку и использовать этот класс в глобальном обработчике исключений для возврата информации об ошибках. Например:

Язык кода:java
копировать
public class ErrorResponse {
    private int status;
    private String message;

    public ErrorResponse(int status, String message) {
        this.status = status;
        this.message = message;
    }

    // ... методы получения и установки
}

Затем,существоватьобщая ситуацияаномальныйпроцессорсерединаиспользоватьErrorResponseКласс возвращает сообщение об ошибке:

Язык кода:java
копировать
@ExceptionHandler(CustomException.class)
public ResponseEntity<ErrorResponse> handleCustomException(CustomException e) {
    ErrorResponse errorResponse = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
}

7. Ограничить определенные исключения из глобальной обработки.

Если вы хотите ограничить глобальную обработку определенных типов исключений, вы можете сделать это двумя следующими способами:

Способ первый:существовать@ExceptionHandlerаннотациясерединаиспользоватьexcludeсвойство

Весной после версии 3.2,@ExceptionHandlerАннотация добавленаexcludeсвойство,позволяет исключить определенныетип исключения Без обработки。ты можешьсуществовать@ExceptionHandlerаннотациясередина Укажите, что исключитьаномальныйтип,Как показано ниже:

Язык кода:java
копировать
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        if (e instanceof SomeSpecificException) {
            // Не обрабатывать исключения типа SomeSpecificException.
            return null;
        }
        // Обработка других типов исключений
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Внутренняя ошибка сервера");
    }

    // Другие методы обработки...
}

Однако,Этот подход не очень элегантен,потому что это требует от тебясуществоватьиметь дело сметод内部进行тип检查ивозвращатьсяnull。Лучший способ - использоватьexcludeсвойствопрямойсуществоватьаннотациясередина排除不需要иметь дело с的аномальныйтип。но,Следует отметить, что,@ExceptionHandlerСама аннотация не даетexcludeсвойство。Чтобы реализовать эту функцию,вам нужно использовать@ControllerAdviceвариант——@RestControllerAdvice,Это позволяет вам определять исключенные типы исключений на уровне класса.

Язык кода:java
копировать
@RestControllerAdvice(exclude = SomeSpecificException.class)
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        // Этот метод не будет обрабатывать исключения типа SomeSpecificException.
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Внутренняя ошибка сервера");
    }

    // Другие методы обработки...
}
Способ 2. Создайте несколько обработчиков исключений.

Другой подход — создать несколько обработчиков исключений, каждый из которых обрабатывает свой набор исключений. Таким образом, вы можете косвенно исключить определенные типы исключений, не включая их. Например:

Язык кода:java
копировать
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({Exception.class, AnotherException.class})
    public ResponseEntity<String> handleMultipleExceptions(Exception e) {
        // Обработка исключений типа Exception и AnotherException
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Внутренняя ошибка сервера");
    }

    // Этот метод не будет обрабатывать исключения типа SomeSpecificException.
}

8. Вывод формата журнала

При глобальной обработке исключений форматированный вывод журналов может помочь нам лучше понять контекстную информацию при возникновении исключений, что упрощает отладку и обнаружение проблем. Вот как реализовать вывод в формате журнала при глобальной обработке исключений:

1. Введение зависимостей

первый,Убедитесь, что вы включили зависимость платформы ведения журнала в свой проект. Возьмите Logback в качестве примера,вам нужносуществоватьpom.xmlдокументсередина Добавьте следующие зависимости:

Язык кода:xml
копировать
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
2. Создайте объект журнала.

В вашем глобальном классе обработчика исключений,Создайте объект журнала. в целом,мы используемSLF4JВ качестве бревенчатого фасада,Затем Выберите конкретную реализацию журнала(нравитьсяLogback)。

Язык кода:java
копировать
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    // ...другой код
}
3. Запись журналов в методах обработки исключений.

В методе глобального обработчика исключений,Использование объекта журналаerror()метод Записыватьаномальныйинформация。Чтобы добиться форматированного вывода,мы можем использовать{}заполнитель,и Воляаномальный Объект передается в качестве аргументаerror()метод。

Язык кода:java
копировать
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
    logger.error("Внутренняя ошибка сервера: {}", e.getMessage(), e);
    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Внутренняя ошибка сервера");
}

В этом примере,мы используемlogger.error()метод Записывать了一个格式化的错误日志。{}заполнитель Воля被e.getMessage()Замените значение,в то же времяаномальныйобъектeтакже будет передано в журналметодсередина,для включения в журнал информации о трассировке стека исключения.

4. Настройте формат журнала.

Чтобы лучше контролировать формат вывода журнала,мы можемсуществоватьsrc/main/resourcesСоздайте каталог с именемlogback-spring.xmlфайлы,Используется для настройки структуры ведения журнала Logback. в этом файле,Мы можем определить формат вывода и уровень журнала.

Язык кода:xml
копировать
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

В этом файле конфигурации,Мы определяем файл с именемSTDOUTконсольный вывод,И установите формат вывода журнала。%d{yyyy-MM-dd HH:mm:ss.SSS}представляет дату и время,%threadУказывает имя потока,%-5levelУказывает уровень журнала(выравнивание по левому краю),%logger{36}Представляет имя экспортера журналов.(перед перехватом36персонажи),%msgпредставляет собой сообщение журнала,%nПредставляет символ новой строки。

Подвести итог

В этой статье объясняется, как использовать Spring Boot优雅地иметь дело собщая ситуацияаномальный。通过创建общая ситуацияаномальныйпроцессор类и использовать@ControllerAdviceи@ExceptionHandlerаннотация,Мы можем легко перехватывать и обрабатывать различные исключения. в то же время,Мы также представилинравиться Хэ Чуан Пользовательский класс исключенийи Возврат пользовательского ответа об Нужна помощь. Я надеюсь, что содержание этой статьи поможет вам лучше справляться с Spring. Глобальное исключение в загрузочном приложении.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose