全局异常处理[Spring MVC]

1 概述

Spring MVC框架中,全局异常处理允许你集中处理应用程序中抛出的各种异常,并以一致的方式向客户端返回错误信息。全局异常处理可以增强应用程序的健壮性和用户体验,特别是在Web应用中。
Spring MVC中有内置的异常处理对象,但是呈现的结果对于用户端不友好,所以实际项目我们一般会使用全局异常处理器处理异常。

2 注解说明

实现全局异常处理时,常见注解有三个:

  • @ControllerAdvice注解
    • 用于描述全局异常处理类。
    • 这个类会被Spring自动扫描并注册为一个全局异常处理对象。
  • ExceptionHandler注解:
    • 用于描述全局异常处理方法
    • 描述方法时,需要指定可以处理的异常类型。
  • @RestControllerAdvice注解
    • 复合注解,是@ControllerAdvice注解和@ResponseBody注解的组合。

3 全局异常处理器使用流程

  • 第1步: 基于异常处理需求,定义全局异常处理类,代码如下:
    工程目录下创建 base.exception.GlobalExceptionHandler
@RestControllerAdvice
public class GlobalExceptionHandler {
    
}
  • 第2步: 创建对应的异常处理方法
    在异常处理方法上添加 @ExceptionHandler 注解
/**
        ex.getMessage()方法:用于捕获异常信息
*/
@ExceptionHandler
public JsonResult doHandleRuntimeException(RuntimeException ex){
    log.error("error is " + ex.getMessage());
    return new JsonResult(StatusCode.OPERATION_FAILED,ex.getMessage());
}

4 整体代码

base.exception.GlobalExceptionHandler

package cn.tedu._03vehicle.base.exception;

import cn.tedu._03vehicle.base.response.JsonResult;
import cn.tedu._03vehicle.base.response.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * RestControllerAdvice 是复合注解,描述的类型为一个全局异常处理对象类型,
 * 等价于:@ControllerAdvice+@ResponseBody
 * 当某个Controller方法中出现了异常,系统底层就会查找有没有定义全局异常处理对象。
 * 这个全局异常处理对象中有没有定义对应的异常处理方法,假如有就调用此方法处理异常。
 */

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     *  @ExceptionHandler 描述的方法为一个异常处理方法,在此注解内部可以定义具体的异常处理
     *  类型(例如RuntimeException),此注解描述的方法需要定义一个异常类型的形式参数,
     *  通过这个参数接收具体的异常对象(也可以接收其异常类型对应的子类类型的异常)。
     */
    @ExceptionHandler
    public JsonResult doHandleIllegalArgumentException(IllegalArgumentException ex){
        log.error("IllegalArgumentException: " + ex.getMessage());
        return new JsonResult(StatusCode.OPERATION_FAILED, ex.getMessage());
    }

    /**
     * 假如用全局异常处理对象处理Controller类中出现的异常,全局异常处理对象会优先查找与Controller
     * 中相匹配的异常处理方法,假如没有,会查找对应异常的父类异常处理方法。
     */
    @ExceptionHandler
    public JsonResult doHandleRuntimeException(RuntimeException ex){
        log.error("IllegalArgumentException is " + ex.getMessage());
        return new JsonResult(StatusCode.OPERATION_FAILED,ex.getMessage());
    }
}

5 关于Throwable

在开发实践中,通常会添加一个处理 Throwable 的方法,它将可以处理所有类型的异常,则不会再出现500错误!
GlobalExceptionHandler中添加处理 Throwable的方法

@ExceptionHandler
public JsonResult doHandleThrowable(Throwable ex){
        String data = ex.getMessage();
        log.error("Throwable:" + data);

        return new JsonResult(StatusCode.THROWABLE_ERROR, data);
}

6 注意事项

  • 在设计全局异常处理时,请确保异常处理器能够覆盖尽可能多的异常类型。
  • 使用恰当的HTTP状态码来区分不同类型的错误。
  • 提供有用的错误信息,但不要泄露敏感信息。
  • 如果可能,记录异常的详细信息以便于调试和追踪问题。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容