[mejora de springboot framework] elegante excepción personalizada captura lo último en toda la red

I. Introducción

En el desarrollo diario de proyectos, las excepciones son comunes, pero cómo manejar la información de excepción de manera más eficiente, para que podamos localizar errores rápidamente, es muy importante, no solo puede mejorar nuestra eficiencia de desarrollo, sino también hacer que su código se vea mejor Cómodo, el proyecto SpringBoot ya ha manejado algunas excepciones, pero puede que no sea adecuado para nosotros, los desarrolladores, por lo que debemos capturar y manejar estas excepciones de manera uniforme.

Si no se realiza el manejo de excepciones, cuando ocurre un error, la información devuelta puede ser la siguiente: inserte la descripción de la imagen aquí

2. Clasificación de anomalías

1. Clasificación de anomalías desde una perspectiva definitoria

inserte la descripción de la imagen aquí

(1).Error

Un error de hardware o sistema operativo encontrado por un programa durante la ejecución. Los errores son fatales para un programa y evitarán que el programa se ejecute. Los errores comunes incluyen desbordamiento de memoria, operación anormal de la propia máquina virtual jvm y ningún método principal en el archivo calss. El programa en sí no puede manejar los errores y solo puede confiar en la intervención externa. El error es un error interno del sistema, que es lanzado por jvm y entregado al sistema para su procesamiento.

(2) Excepción

Es una situación inesperada que se puede esperar en el funcionamiento normal del programa. Por ejemplo, la conexión de la base de datos se interrumpe, el puntero nulo y el subíndice de la matriz están fuera de los límites. Las excepciones pueden dar lugar a una finalización anómala del programa, o pueden detectarse con antelación, capturarse y gestionarse, de modo que el programa pueda seguir ejecutándose. EXCEPTION (excepción) se divide en excepción de compilación (detectable) y excepción de tiempo de ejecución (indetectable) según su naturaleza.

a. Excepción en tiempo de compilación

También conocidas como excepciones verificables, las excepciones generalmente son causadas por errores de sintaxis y factores ambientales (recursos externos). Como excepción de entrada y salida IOException, operación de base de datos SQLException. Su peculiaridad es que el lenguaje Java exige que todas las excepciones que no sean de tiempo de ejecución sean capturadas y manejadas. Fortalecer la solidez y seguridad de los programas a través del código de conducta.

B. Excepción de tiempo de ejecución

También conocidas como excepciones no verificadas RuntimeException, estas excepciones generalmente son causadas por errores lógicos del programa, es decir, errores semánticos. Por ejemplo, excepción aritmética, excepción de puntero nulo NullPointerException, subíndice fuera de los límites IndexOutOfBoundsException. Las excepciones de tiempo de ejecución deben exponerse durante la prueba del programa y ser depuradas por el programador, en lugar de ser detectadas.

2. Clasificar las excepciones desde una perspectiva de desarrollo

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

(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. 以上对于未知异常的处理就完事了,看看效果,模拟一个空指针异常的接口,访问结果如下

inserte la descripción de la imagen aquí

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

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

En respuesta a los problemas anteriores, podemos capturar una HttpException autodefinida en GlobalExceptionAdvice , otras clases de error son HttpException , y HttpException hereda la clase RuntimeException, para que podamos implementar el lanzamiento de nuestros propios errores definidos.La clase HttpException específica es como sigue:

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;
    }
}

复制代码

También necesitamos definir otras subclases específicas que hereden las clases anteriores, por ejemplo NotFoundException, el siguiente código:

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

La clase GlobalExceptionAdvicese puede capturar HttpExceptionen el código de la siguiente manera:

  @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 lo usamos, por ejemplo:inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

Cuando no se puede encontrar la información del usuario, la información devuelta es la siguiente:

inserte la descripción de la imagen aquí

A partir de esto, podemos ver que el código de estado es 404 definido por nosotros mismos, y el código devuelto es lo que pasamos.


Al final de este artículo, el próximo artículo presentará la verificación de parámetros del manejo unificado de excepciones, gracias por leer.

Supongo que te gusta

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