[aprimoramento da estrutura springboot] exceção personalizada elegante captura o mais recente em toda a rede

I. Introdução

No desenvolvimento diário de projetos, exceções são comuns, mas como lidar com informações de exceção com mais eficiência, para que possamos localizar bugs rapidamente, é muito importante, não apenas pode melhorar nossa eficiência de desenvolvimento, mas também fazer seu código parecer melhor Confortável, o projeto SpringBoot já tratou algumas exceções, mas pode não ser adequado para nós desenvolvedores, então precisamos capturar e tratar essas exceções de maneira uniforme.

Se o tratamento de exceção não for realizado, quando ocorrer um erro, as informações retornadas podem ser as seguintes: insira a descrição da imagem aqui

2. Classificação de anomalias

1. Classificação de anomalias de uma perspectiva de definição

insira a descrição da imagem aqui

(1). Erro

Um erro de hardware ou sistema operacional encontrado por um programa durante a execução. Os erros são fatais para um programa e impedirão a execução do programa. Erros comuns incluem estouro de memória, operação anormal da própria máquina virtual jvm e nenhum método principal no arquivo calss. O próprio programa não pode lidar com erros e só pode contar com intervenção externa. Error é um erro interno do sistema, que é lançado pela jvm e entregue ao sistema para processamento.

(2). Exceção

É uma situação inesperada que pode ser esperada na operação normal do programa. Por exemplo, a conexão com o banco de dados é interrompida, o ponteiro nulo e o subscrito da matriz está fora dos limites. As exceções podem levar ao encerramento anormal do programa ou podem ser detectadas antecipadamente, capturadas e tratadas, para que o programa possa continuar a ser executado. EXCEPTION (exceção) é dividido em exceção de compilação (detectável) e exceção de tempo de execução (indetectável) de acordo com sua natureza.

a. Exceção em tempo de compilação

Também conhecidas como exceções verificáveis, as exceções geralmente são causadas por erros de sintaxe e fatores ambientais (recursos externos). Como exceção de entrada e saída IOException, operação de banco de dados SQLException. Sua peculiaridade é que a linguagem Java exige que todas as exceções que não sejam de tempo de execução sejam capturadas e tratadas. Fortalecer a robustez e a segurança dos programas por meio do código de conduta.

b. Exceção de tempo de execução

Também conhecidas como exceção não verificada RuntimeException, essas exceções geralmente são causadas por erros de lógica do programa, ou seja, erros semânticos. Por exemplo, exceção aritmética, exceção de ponteiro nulo NullPointerException, subscrito fora dos limites IndexOutOfBoundsException. As exceções de tempo de execução devem ser expostas durante o teste do programa e depuradas pelo programador, em vez de serem detectadas.

2. Classifique as exceções de uma perspectiva de desenvolvimento

我们也可以把异常分类已知异常未知异常

(1). 已知异常

代表我们可以控制的异常,比如当一个资源没找到的时候,要返回给前端,抛出资源没有找到。 当校验参数的时候,参数缺失,抛出参数缺失给前端。

(2). 未知异常

代表我们也不知道什么时候程序可能会报错,可能某个地方判断不严谨,导致空指针或下标越界等。

三、如何优雅的进行异常捕获(重点是已知异常的处理)

我们知道,使用springboot的时候,我们可以使用@ControllerAdvice和@ExceptionHandler对异常进行全局异常捕获,但如何做,才能使异常捕获更加的优雅呢?

我们可以从已知异常未知异常进行自定义的异常处理。

1. 未知异常的处理

  1. 新建一个GlobalExceptionAdvice全局异常处理的类,加上@ControllerAdvice注解
  2. 捕获Exception.class
    @ExceptionHandler(Exception.class)
    @ResponseBody
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    public ReturnMsgEntity handlerException(HttpServletRequest request, Exception e) {
        String uri = request.getRequestURI();
        String method = request.getMethod();
        ReturnMsgEntity message = new ReturnMsgEntity(9999, codeConfiguration.getMessage(9999), null, method + "  " + uri);
        return message;
    }
复制代码

解释: 为了防止硬编码,写了一个codeConfiguration配置类,作用是读取某个路径下的文件,封装成一个map

@Component
@ConfigurationProperties(prefix="aisino")
@PropertySource("classpath:config/exception-code.properties")
public class ExceptionCodeConfiguration {
    private Map<Integer,String> codes = new HashMap<>();

    public  String getMessage(int code){
        return codes.get(code);
    }

    public Map<Integer, String> getCodes() {
        return codes;
    }

    public void setCodes(Map<Integer, String> codes) {
        this.codes = codes;
    }
}
复制代码

exception-code.properties配置文件如下:

aisino.codes[9999] = 服务器未知异常

aisino.codes[10000] = 通用异常

aisino.codes[10001] = 通用参数错误

aisino.codes[0] = ok

aisino.codes[10002] = 资源未找到

复制代码
  1. 以上对于未知异常的处理就完事了,看看效果,模拟一个空指针异常的接口,访问结果如下

insira a descrição da imagem aqui

2. 已知异常的处理(重点)

已知异常有很多种,比如禁止访问,参数缺失,没有找到资源,没有认证,难道我们要把每个错误都写在GlobalExceptionAdvice类中吗?这样写是不是不容易维护,比如当资源不存在该如何抛出呢?

Em resposta aos problemas acima, podemos capturar um HttpException autodefinido em GlobalExceptionAdvice , outras classes de erro são HttpException e HttpException herda a classe RuntimeException , para que possamos implementar o lançamento de nossos próprios erros definidos. segue:

public class HttpException extends RuntimeException{
    //自定义错误码
    protected Integer code;
    // 默认的状态码
    protected Integer httpStatusCode = 500;

    public Integer getCode() {
        return code;
    }

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

    public Integer getHttpStatusCode() {
        return httpStatusCode;
    }

    public void setHttpStatusCode(Integer httpStatusCode) {
        this.httpStatusCode = httpStatusCode;
    }
}

复制代码

Também precisamos definir outras subclasses específicas que herdam as classes acima, por exemplo NotFoundException, o seguinte código:

public class NotFoundException extends HttpException {
    public NotFoundException(int code){
        this.httpStatusCode = 404;
        this.code = code;
    }
}
复制代码

A classe GlobalExceptionAdvicepode ser capturada HttpExceptionno código da seguinte forma:

  @ExceptionHandler(HttpException.class)
    @ResponseBody
    public ResponseEntity<ReturnMsgEntity> handlerHttpException(HttpServletRequest request, HttpException e) {
        // 获得请求路径
        String requestUrl = request.getRequestURI();
        // 获得请求方法
        String method = request.getMethod();
        // e.getcode 根据我们自定义的状态码获取具体的错误信息
        ReturnMsgEntity message = new ReturnMsgEntity(e.getCode(), codeConfiguration.getMessage(e.getCode()), null, method + "  " + requestUrl);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        // 设置我们自定义的http状态码,比如404对应资源没找到,前端收到的状态码不是200,是404了
        HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());
        ResponseEntity<ReturnMsgEntity> responseEntity = new ResponseEntity<>(message, headers, httpStatus);
        return responseEntity;

    }
复制代码

Finalmente, usamos, por exemplo:insira a descrição da imagem aqui

insira a descrição da imagem aqui

Quando as informações do usuário não podem ser encontradas, as informações retornadas são as seguintes:

insira a descrição da imagem aqui

A partir disso, podemos ver que o código de status é 404 definido por nós mesmos e o código retornado é o que passamos.


No final deste artigo, o próximo artigo apresentará a verificação de parâmetros do tratamento unificado de exceções, obrigado pela leitura.

Acho que você gosta

Origin juejin.im/post/7080023434448601096
Recomendado
Clasificación