SpringBoot统一响应格式及统一异常处理

作者:JK凯 时间:2022-08-30 08:03:08 

在我们开发SpringBoot后端服务时,一般需要给前端统一响应格式,方便前端调试及配置错误提示等等。这篇文章讲讲实际工作中统一响应格式及统一异常处理是如何做的。

一、统一响应基础类

在项目中对应工具类或Vo层来创建我们的统一响应类

SpringBoot统一响应格式及统一异常处理

ResponseResult:

import com.fasterxml.jackson.annotation.JsonInclude;
import com.zhang.enums.AppHttpCodeEnum;
import java.io.Serializable;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> implements Serializable {
   private Integer code;
   private String msg;
   private T data;
   public ResponseResult() {
       this.code = AppHttpCodeEnum.SUCCESS.getCode();
       this.msg = AppHttpCodeEnum.SUCCESS.getMsg();
   }
   public ResponseResult(Integer code, T data) {
       this.code = code;
       this.data = data;
   }
   public ResponseResult(Integer code, String msg, T data) {
       this.code = code;
       this.msg = msg;
       this.data = data;
   }
   public ResponseResult(Integer code, String msg) {
       this.code = code;
       this.msg = msg;
   }
   public static ResponseResult errorResult(int code, String msg) {
       ResponseResult result = new ResponseResult();
       return result.error(code, msg);
   }
   public static ResponseResult okResult() {
       ResponseResult result = new ResponseResult();
       return result;
   }
   public static ResponseResult okResult(int code, String msg) {
       ResponseResult result = new ResponseResult();
       return result.ok(code, null, msg);
   }
   public static ResponseResult okResult(Object data) {
       ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getMsg());
       if (data != null) {
           result.setData(data);
       }
       return result;
   }
   public static ResponseResult errorResult(AppHttpCodeEnum enums) {
       return setAppHttpCodeEnum(enums, enums.getMsg());
   }
   public static ResponseResult errorResult(AppHttpCodeEnum enums, String msg) {
       return setAppHttpCodeEnum(enums, msg);
   }
   public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums) {
       return okResult(enums.getCode(), enums.getMsg());
   }
   private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String msg) {
       return okResult(enums.getCode(), msg);
   }
   public ResponseResult<?> error(Integer code, String msg) {
       this.code = code;
       this.msg = msg;
       return this;
   }
   public ResponseResult<?> ok(Integer code, T data) {
       this.code = code;
       this.data = data;
       return this;
   }
   public ResponseResult<?> ok(Integer code, T data, String msg) {
       this.code = code;
       this.data = data;
       this.msg = msg;
       return this;
   }
   public ResponseResult<?> ok(T data) {
       this.data = data;
       return this;
   }
   public Integer getCode() {
       return code;
   }
   public void setCode(Integer code) {
       this.code = code;
   }
   public String getMsg() {
       return msg;
   }
   public void setMsg(String msg) {
       this.msg = msg;
   }
   public T getData() {
       return data;
   }
   public void setData(T data) {
       this.data = data;
   }
}

里面还有用到一个响应的枚举类AppHttpCodeEnum,接下来我们创建这个枚举类

二、响应枚举类

SpringBoot统一响应格式及统一异常处理

AppHttpCodeEnum:

public enum AppHttpCodeEnum {
   // 成功
   SUCCESS(200, "操作成功"),
   // 登录
   NEED_LOGIN(401, "需要登录后操作"),
   NO_OPERATOR_AUTH(403, "无权限操作"),
   SYSTEM_ERROR(500, "出现错误"),
   USERNAME_EXIST(501, "用户名已存在"),
   PHONENUMBER_EXIST(502, "手机号已存在"), EMAIL_EXIST(503, "邮箱已存在"),
   REQUIRE_USERNAME(504, "必需填写用户名"),
   CONTENT_NOT_NULL(506, "评论内容不能为空"),
   FILE_TYPE_ERROR(507, "文件类型错误"),
   USERNAME_NOT_NULL(508, "用户名不能为空"),
   NICKNAME_NOT_NULL(509, "昵称不能为空"),
   PASSWORD_NOT_NULL(510, "密码不能为空"),
   EMAIL_NOT_NULL(511, "邮箱不能为空"),
   NICKNAME_EXIST(512, "昵称已存在"),
   LOGIN_ERROR(505, "用户名或密码错误");
   int code;
   String msg;
   AppHttpCodeEnum(int code, String errorMessage) {
       this.code = code;
       this.msg = errorMessage;
   }
   public int getCode() {
       return code;
   }
   public String getMsg() {
       return msg;
   }
}

一般我们在这个枚举类中管理需要响应的错误codemsg

三、统一响应格式使用

在对应的controller或者service里面使用统一响应类

SpringBoot统一响应格式及统一异常处理

  • 成功: ResponseResult.okResult()

  • 失败: ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR), 参数传入我们定义的响应枚举类

四、统一异常处理

1. 自定义异常

为什么我们需要自定义异常?因为在某些情况下,我们需要返回我们自定义的响应格式非常不方便,如在处理用户鉴权或token校验的时候,因为像这些部分我们一般都是在单独的工具类中去处理,这时候如果报错其实就可以抛出我们自定义的异常,交由我们全局的异常处理去统一返回响应。

  • exception包下新建SystemException

  • SystemException继承RuntimeException

具体实现代码如下

exception.SystemException:

import com.jk.enums.AppHttpCodeEnum;
public class SystemException extends RuntimeException{
   private int code;
   private String msg;
   public int getCode() {
       return code;
   }
   public String getMsg() {
       return msg;
   }
   public SystemException(AppHttpCodeEnum appHttpCodeEnum) {
       super(appHttpCodeEnum.getMsg());
       this.code = appHttpCodeEnum.getCode();
       this.msg = appHttpCodeEnum.getMsg();
   }
}

目前只是自定义了异常,我们还需要对自定义的异常进行处理,返回统一的响应格式。

2.异常处理

  • handler.exception包下新建GlobalExceptionHandler处理类

  • @RestControllerAdvice是组合注解,由@ControllerAdvice@ResponseBody组成,标明是一个统一异常处理的类,并把返回结果封装在ResponseBody

  • @Slf4jLombok实现日志输出的注解

  • @ExceptionHandler标明该方法处理哪些异常

具体代码实现如下:

handler.exception.GlobalExceptionHandler:

import com.jk.enums.AppHttpCodeEnum;
import com.jk.exception.SystemException;
import com.jk.vo.ResponseResult;
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 ResponseResult systemExceptionHandler(SystemException e) {
       log.error("出现了异常! {}", e);
       return ResponseResult.errorResult(e.getCode(), e.getMsg());
   }
   @ExceptionHandler(Exception.class)
   public ResponseResult exceptionHandler(Exception e) {
       log.error("出现了异常! {}", e);
       return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR.getCode(), e.getMessage());
   }
}

可以看到我们除了处理自定义异常SystemException外,还对Exception就是其他我们无法预料到的异常做了一个兜底。

3.自定义异常使用

在需要抛出异常的地方:

throw new SystemException(AppHttpCodeEnum.LOGIN_ERROR);

前端接收到的响应是:

{
   "code": 505,
   "msg": "用户名或密码错误"
}

这样就比接收到500错误也不知道错误原因好多了。

来源:https://juejin.cn/post/7226994337123549242

标签:SpringBoot,统一响应格式,统一异常处理
0
投稿

猜你喜欢

  • Kotlin协程的启动方式介绍

    2022-05-26 10:29:27
  • C#微信公众号开发之用户管理

    2023-04-13 02:40:12
  • C#的并发机制优秀在哪你知道么

    2022-11-09 09:44:35
  • C#中ArrayList的使用方法

    2023-01-26 10:20:47
  • Java实现AWT四大事件的详细过程

    2023-11-28 18:39:52
  • C#开发微信门户及应用(5) 用户分组信息管理

    2022-08-03 04:52:20
  • Android开发自学笔记(六):声明权限和Activity

    2021-05-26 07:25:49
  • SpringBoot实现项目健康检查与监控

    2023-10-28 19:14:25
  • C# List 并发丢数据问题原因及解决方案

    2023-06-18 17:53:54
  • 深入浅出讲解Java集合之Collection接口

    2023-05-27 05:53:38
  • 简单记事本java源码实例

    2023-11-26 02:03:17
  • Java基础教程之组合(composition)

    2022-08-02 19:12:32
  • Java日常练习题,每天进步一点点(54)

    2023-08-18 21:55:17
  • Android自定义控件实现支付宝记账饼图

    2022-04-19 13:27:02
  • C# NAudio 库的各种常见使用方式之播放 录制 转码 音频可视化

    2023-06-20 04:14:16
  • Android Hilt依赖注入的使用讲解

    2023-11-23 02:13:50
  • android 微信 sdk api调用不成功解决方案

    2023-08-27 15:31:45
  • c#批量上传图片到服务器示例分享

    2022-09-12 10:16:24
  • ImageView 实现Android colorPikcer 选择器的示例代码

    2023-03-12 03:21:37
  • SpringBoot2零基础到精通之数据与页面响应

    2022-08-25 22:26:41
  • asp之家 软件编程 m.aspxhome.com