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
投稿

猜你喜欢

  • Java IO流—异常及捕获异常处理 try…catch…finally

    2023-03-14 07:35:52
  • java15新功能的详细讲解

    2023-08-23 04:40:21
  • SpringBoot 创建web项目并部署到外部Tomcat

    2023-09-15 18:25:04
  • Java Springboot的目的你知道吗

    2022-12-20 14:16:24
  • Springboot Thymeleaf模板文件调用Java类静态方法

    2023-11-25 05:34:47
  • Android控件之SlidingDrawer(滑动式抽屉)详解与实例分享

    2023-07-27 09:26:18
  • Java File类提供的方法与操作

    2023-08-29 09:10:41
  • 学习SpringBoot容器功能及注解原理

    2023-11-24 22:06:17
  • java实现单词小游戏

    2023-11-25 05:03:33
  • startActivityForResult和setResult案例详解

    2023-09-15 19:13:33
  • Mybatis-Spring源码分析图解

    2023-07-18 13:35:07
  • Java修饰符 abstract,static,final 的区别详解

    2023-12-19 22:11:25
  • Springboot jar主清单属性丢失解决方案

    2022-04-06 05:30:26
  • Java以命令模式设计模式

    2023-11-24 21:27:52
  • Spring Boot 工程的创建和运行(图文)

    2022-06-26 15:39:49
  • Springboot整合mqtt服务的示例代码

    2022-07-20 02:58:01
  • Java实现的Base64加密算法示例

    2023-10-29 00:37:08
  • Spring Boot thymeleaf模板引擎的使用详解

    2022-07-27 07:42:54
  • 关于java中构造函数的一些知识详解

    2023-11-27 22:09:11
  • Java实例讲解动态代理

    2023-03-21 22:56:45
  • asp之家 软件编程 m.aspxhome.com