1 前言
在上一篇文章中介绍了SpringBoot项目中统一接口返回类型(不懂得可以看看这篇文章),将返回类型统一后,前端人员就能很方便的知晓本次请求的信息了,但是一旦项目中出现异常,接口的响应内容就如下图所示,违背了我们统一返回类型的初衷,尽管我们可以使用try/catch对异常进行捕获,但是总会有异常是我们意料不到的,全局异常处理加上统一接口返回类型就能很好解决这个问题。下面就来介绍文章的主角——全局异常处理。
2 项目预览
TestController:测试ControllerStatus:状态码枚举类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 }
使用全局异常处理后,无论项目中是否出现异常,接口都能够返回我们想要的数据格式了,也有利于项目中日志的记录(这个后面的文章会涉及)。