SpringBoot全局异常处理

113 阅读2分钟

1 前言

在上一篇文章中介绍了SpringBoot项目中统一接口返回类型(不懂得可以看看这篇文章),将返回类型统一后,前端人员就能很方便的知晓本次请求的信息了,但是一旦项目中出现异常,接口的响应内容就如下图所示,违背了我们统一返回类型的初衷,尽管我们可以使用try/catch对异常进行捕获,但是总会有异常是我们意料不到的,全局异常处理加上统一接口返回类型就能很好解决这个问题。下面就来介绍文章的主角——全局异常处理

img

2 项目预览

img
  • TestController:测试Controller
  • Status:状态码枚举类
  • Result:接口返回对象
  • SystemException:自定义异常类
  • GlobalExceptionHandler:全局异常处理类

3 实现

3.1 自定义异常类

package com.example.exception;

import com.example.domain.vo.Status;

/**
 * 自定义异常
 */
public class SystemException extends RuntimeException {
   private final int code;

   public SystemException(int code, String msg) {
      super(msg);
      this.code = code;
   }

   public SystemException(Status status) {
      super(status.getMsg());
      this.code = status.getCode();
   }

   public int getCode() {
      return code;
   }
}

3.2 添加状态码

package com.example.domain.vo;

public enum Status {
   SUCCESS(200, "成功!"),
   FAIL(400, "失败!"),
   SYSTEM_ERROR(401, "系统异常");

   private final int code;
   private final String msg;

   Status(int code, String msg) {
      this.code = code;
      this.msg = msg;
   }

   public int getCode() {
      return code;
   }

   public String getMsg() {
      return msg;
   }
}

添加一个SYSTEM_ERROR状态码

3.3 新增全局异常处理类

package com.example.handle;

import com.example.domain.vo.Result;
import com.example.exception.SystemException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
   @ExceptionHandler(SystemException.class)
   public Result doSystemException(SystemException e) {
      log.info("出现系统异常!", e);

      return Result.fail(e.getCode(), e.getMessage());
   }

   @ExceptionHandler(Exception.class)
   public Result exceptionHandler(Exception e) {
      log.error("出现未知异常!", e);

      return Result.fail(500, "网络繁忙,请稍后再试!");
   }
}
  • @RestControllerAdvice: 这个注解是 Spring MVC 提供的用于全局处理异常的注解。它结合了 @ControllerAdvice@ResponseBody,用于处理控制器层抛出的异常并返回 JSON 格式的响应。
  • @ExceptionHandler(SystemException.class): 这个注解标注在方法上,表示该方法用于处理 SystemException 类型的异常。当系统抛出 SystemException 异常时,Spring 会调用这个方法来处理异常。
  • exceptionHandler这个方法用于捕获项目中未知的异常

4 测试

package com.example.controller;

import com.example.domain.vo.Result;
import com.example.domain.vo.Status;
import com.example.exception.SystemException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@ResponseBody
public class TestController {
   @GetMapping("/test")
   public Result test() {
      //抛出异常
      if (true) throw new SystemException(Status.SYSTEM_ERROR);

      return Result.success();
   }
}

接口响应如下

{ "code": 401, "msg": "系统异常", "data": null }

使用全局异常处理后,无论项目中是否出现异常,接口都能够返回我们想要的数据格式了,也有利于项目中日志的记录(这个后面的文章会涉及)。