Compartilhamento de tecnologia

SpringBoot: resposta unificada SpringBoot e tratamento unificado de exceções

2024-07-06

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

I. Introdução

Ao desenvolver aplicativos Spring Boot, a forma como os resultados de resposta e exceções são tratados tem um impacto crucial na capacidade de manutenção, escalabilidade e colaboração da equipe do projeto. Resultados de resposta dispersos e lógica de tratamento de exceções geralmente levam a código redundante que é difícil de entender e manter. Portanto, o retorno unificado de resultados e o tratamento unificado de exceções são uma das principais estratégias para melhorar a qualidade do projeto.

2. Retorno de resultado unificado

Unificar os retornos de resultados geralmente significa definir um formato de resposta padrão para todos os métodos do controlador. Isso pode ser feito criando uma ou mais classes de entidade de resposta que contenham campos comuns, como código de status, mensagem e dados. Depois que o método do controlador tiver processado a lógica de negócios, ele preencherá esses campos e os retornará ao cliente.

A seguir, vamos dar uma olhada em como obter um retorno de resultado unificado no SpringBoot.

1. Defina um objeto de resposta comum

Crie um objeto de resposta genérico, defina cenários de retorno de sucesso e falha e garanta que o objeto de retorno genérico seja usado na interface.

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. Defina o código de status de resposta da interface

Definir um conjunto comum de códigos de status é uma das principais chaves para o retorno unificado de resultados. Essa abordagem não apenas melhora a usabilidade e a manutenção da API, mas também permite que o cliente analise e processe dados de resposta com mais eficiência. Ela também fornece aos desenvolvedores de API um padrão claro e consistente a ser seguido.

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. Definir métodos unificados de tratamento de sucesso e falha

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. O controlador responde uniformemente aos resultados

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

3. Tratamento unificado de exceções

O tratamento unificado de exceções usa um manipulador de exceções global para capturar e tratar exceções lançadas no controlador. Essa abordagem evita escrever código duplicado de tratamento de exceções em cada método do controlador e também torna a lógica de tratamento de exceções mais centralizada e fácil de gerenciar.

@ConselhoRestController
@RestControllerAdvice é uma anotação combinada, que é uma combinação de @ControllerAdvice e @ResponseBody. É usado principalmente para fornecer configuração global para a camada do controlador, como tratamento de exceções, vinculação de dados, pré-processamento de dados, etc. Como contém @ResponseBody, todos os métodos processados ​​por @RestControllerAdvice gravarão o valor de retorno no corpo da resposta HTTP por padrão e definirão o Content-Type apropriado.

@ExceçãoHandler
A anotação @ExceptionHandler é usada para marcar um método que trata exceções lançadas no controlador. Quando um método no controlador lança uma exceção, o Spring procurará um método anotado @ExceptionHandler que possa tratar a exceção. Nesse caso, o método é chamado e sua resposta é retornada.

Perceber

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

1. Defina classes de exceção de negócios

As classes de exceção unificadas podem ajudá-lo a gerenciar melhor erros e exceções, tornando o tratamento de erros em todo o sistema mais consistente e previsível.

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. Manipulador de exceção global

@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. Processamento e uso unificados

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

        return ResponseResult.success("success");
    }

Benefícios de usar o tratamento unificado de exceções

reutilização de código: evite escrever resultados de resposta e códigos de tratamento de exceções semelhantes em vários locais.

De fácil manutenção: Quando o formato de resposta ou a lógica de tratamento de exceções precisa ser modificado, ele só precisa ser modificado em um local.

Trabalho em equipe: os membros da equipe podem compreender e seguir mais facilmente os padrões de codificação unificados.

Escalabilidade: se você precisar adicionar novos tipos de resposta ou lógica de tratamento de exceções, basta estender os existentes.