Обмен технологиями

SpringBoot: унифицированный ответ SpringBoot и унифицированная обработка исключений.

2024-07-06

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Введение

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

2. Единый возврат результатов

Унификация возвращаемых результатов обычно означает определение стандартного формата ответа для всех методов контроллера. Этого можно добиться, создав один или несколько классов сущностей ответа, которые содержат общие поля, такие как код состояния, сообщение и данные. После того как метод контроллера обработает бизнес-логику, он заполнит эти поля и вернет ее клиенту.

Далее давайте посмотрим, как добиться унифицированного возврата результатов в SpringBoot.

1. Определите общий объект ответа

Создайте универсальный объект ответа, определите сценарии успешного и неудачного возврата и убедитесь, что универсальный объект возврата используется в интерфейсе.

public class ResponseResult {

    private int code;

    private String message;

    private Object data;

    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setData(data);
        responseResult.setCode(ResultEnum.SUCCESS.code);
        return responseResult;
    }

    public static ResponseResult error(ResultEnum resultEnum) {
        return error(resultEnum, resultEnum.message);
    }

    public static ResponseResult error(ResultEnum resultEnum, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(resultEnum.code);
        responseResult.setMessage(message);
        return responseResult;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

2. Определите код состояния ответа интерфейса.

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

public enum ResultEnum {

    SUCCESS(200 ,"请求处理成功"),
    SERVICE_ERROR(500, "服务器异常,请稍后重试");

    public final Integer code;

    public final String message;

    ResultEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

3. Определить унифицированные методы обработки успехов и неудач.

public class ResponseResult {

    private int code;

    private String message;

    private Object data;

    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setData(data);
        responseResult.setCode(ResultEnum.SUCCESS.code);
        return responseResult;
    }

    public static ResponseResult error(ResultEnum resultEnum) {
        return error(resultEnum, resultEnum.message);
    }

    public static ResponseResult error(ResultEnum resultEnum, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(resultEnum.code);
        responseResult.setMessage(message);
        return responseResult;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

4. Контроллер единообразно реагирует на результаты

@GetMapping("/testResult")
 public ResponseResult test() {
     // 模拟业务逻辑
     try {
         // 假设这里有一些业务逻辑
         return ResponseResult.success("success");
     } catch (Exception e) {
         // 捕获异常并返回错误信息
         return ResponseResult.error(ResultEnum.SERVICE_ERROR);
     }
 }

3. Единая обработка исключений

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

@RestControllerAdvice
@RestControllerAdvice — это комбинированная аннотация, представляющая собой комбинацию @ControllerAdvice и @ResponseBody. В основном он используется для обеспечения глобальной конфигурации уровня контроллера, такой как обработка исключений, привязка данных, предварительная обработка данных и т. д. Поскольку он содержит @ResponseBody, все методы, обрабатываемые через @RestControllerAdvice, по умолчанию записывают возвращаемое значение в тело ответа HTTP и устанавливают соответствующий Content-Type.

@ExceptionHandleр
Аннотация @ExceptionHandler используется для обозначения метода, который обрабатывает исключения, создаваемые в контроллере. Когда метод в контроллере генерирует исключение, Spring будет искать аннотированный метод @ExceptionHandler, который может обработать это исключение. Если да, то вызывается метод и возвращается его ответ.

Уведомление

当使用@ControllerAdvice时,我们需要将@ResponseBody添加到异常处理方法上。
如果我们使用@RestControllerAdvice,就不需要添加。

1. Определите классы бизнес-исключений

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

public class BusinessException extends RuntimeException{

    private final ResultEnum resultEnum;

    public BusinessException(ResultEnum resultEnum, String message) {
        super(message);
        this.resultEnum = resultEnum;
    }

    public BusinessException(ResultEnum resultEnum) {
        this(resultEnum, resultEnum.message);
    }


}

2. Глобальный обработчик исключений

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({BusinessException.class})
    public ResponseResult handleBusinessException(BusinessException businessException, HttpServletRequest request) {
        // 想处理的业务
        return ResponseResult.error(ResultEnum.SERVICE_ERROR, businessException.getMessage());
    }

    /**
     * 其他异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseResult handleOtherExceptions(Exception e) {
        // 这里可以根据不同的异常类型返回不同的状态码和消息
        // 但为了简单起见,这里只返回一个通用的错误信息
        return ResponseResult.error(ResultEnum.SERVICE_ERROR);
    }

}

3. Унифицированная обработка и использование.

@GetMapping("/testException1")
    public ResponseResult test1() {
        if (true) {
            // 业务场景
            throw new BusinessException(ResultEnum.SERVICE_ERROR);
        }

        return ResponseResult.success("success");
    }

Преимущества использования унифицированной обработки исключений

повторное использование кода: избегайте записи одинаковых результатов ответа и кодов обработки исключений в нескольких местах.

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

Командная работа: Членам команды будет легче понимать и соблюдать единые стандарты кодирования.

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