springboot返回统一的json标准格式(代码片段)

pcdd pcdd     2022-12-05     666

关键词:

  1. 自定义状态码枚举类
  2. 封装返回结果
  3. 全局异常捕获处理,使用@RestControllerAdvice注解
  4. 拦截Controller方法的返回值,统一处理返回值/响应体
  5. 创建Controller,准备测试
  6. 请求接口,查看响应结果

近年来,随着移动互联网的发展,各种类型的客户端层出不穷。如果不统一数据接口,则会造成冗余编码,增加成本。RESTful风格的API正适合通过一套统一的接口为PC、手机APP等设备提供数据服务。

为了保障前后端数据交换的顺畅,建议规范数据的返回,并采用固定的数据格式封装。如:
返回成功信息的JSON格式如下


  "code": 200,
  "msg": "操作成功",
  "data": "hello jenkins"

返回异常信息的JSON格式如下


  "code": 500,
  "msg": "系统异常,请稍后重试:/ by zero"

实现步骤如下

1. 自定义状态码枚举类(不是HTTP状态码)

@AllArgsConstructor
@Getter
public enum StatusCodeEnum 
    SC200(200, "操作成功"),
    SC999(999, "操作失败"),
    SC401(401, "匿名用户访问权限资源时的异常"),
    SC403(403, "无访问权限,请联系管理员授予权限"),
    SC404(404, "请求的资源不存在"),
    SC500(500, "系统异常,请稍后重试"),
    // ...略
    private final Integer code;
    private final String msg;

2. 封装返回结果

类名可任意取,可根据个人习惯或项目编码规约选择。比如Result、ResultXxx、R、ApiResult、Response、ResponseXxx等等,这里命名为ApiResult

@Data
public class ApiResult<T> implements Serializable 
    private Integer code;
    private String msg;
    private T data;

    public static <T> ApiResult<T> success(T data) 
        return ApiResult.success(StatusCodeEnum.SC200.getMsg(), data);
    

    public static <T> ApiResult<T> success(String msg, T data) 
        ApiResult<T> apiResult = new ApiResult<>();
        apiResult.setCode(StatusCodeEnum.SC200.getCode());
        apiResult.setMsg(msg);
        apiResult.setData(data);
        return apiResult;
    

    public static <T> ApiResult<T> fail(Integer code, String msg) 
        ApiResult<T> apiResult = new ApiResult<>();
        apiResult.setCode(code);
        apiResult.setMsg(msg);
        return apiResult;
    

3. 全局异常捕获处理,使用@RestControllerAdvice注解。

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler 
    /**
     * 捕获其他异常
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public ApiResult<String> handle(Exception e) 
        log.error("全局异常信息:", e.getMessage());
        return ApiResult.fail(StatusCodeEnum.SC500.getCode(), StatusCodeEnum.SC500.getMsg() + ":" + e.getMessage());
    

注解功能
@RestControllerAdviceRestController的增强类,可用于实现全局异常处理器
@ExceptionHandler统一处理某一类异常,从而减少代码重复率和复杂度,比如要获取自定义异常可以@ExceptionHandler(BusinessException.class)
@ResponseStatus指定客户端收到的http状态码

注:请求进来 会按照 filter -> interceptor -> controllerAdvice -> aspect -> controller的顺序调用,
404异常(NoHandlerFoundException)是无法通过这种方式捕获的,因为在Filter层发生的异常都会到Spring默认的异常处理。如果你在配置文件配置了server.error.path的话,就会使用你配置的异常处理地址,如果没有就会使用你配置的error.path路径地址,如果还是没有,默认使用/error来作为发生异常的处理地址。如果想要替换默认的非Controller异常处理直接实现Spring提供的ErrorController接口就行了。

第四步是重点

4. 拦截Controller方法的返回值,统一处理返回值/响应体。

因为我们后面每写一个接口都需要调用ApiResult.success()这行代码对结果进行包装,重复劳动,浪费体力,我们只需要实现SpringBoot提供的ResponseBodyAdvice接口即可解决这一问题。

@RestControllerAdvice
public class ApiResultWrapper implements ResponseBodyAdvice<Object> 

    /**
     * 是否支持advice功能
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) 
        return true;
    

    /**
     * 对返回的数据进行处理
     */
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) 
        if (o instanceof String) 
            return JSON.toJSONString(ApiResult.success(o));
        
        // 这个判断的作用:防止全局异常处理后返回的结果(类型为ApiResult)再次被包装
        if (o instanceof ApiResult) 
            return o;
        
        return ApiResult.success(o);
    
    

5. 创建Controller,定义两个方法,让第二个方法抛异常

实现ResponseBodyAdvice接口后,方法的返回值类型就可以不再是先前统一的ApiResult了。

@RestController
public class TestController 

    @GetMapping("/test1")
    public String test1() 
        return "当前时间:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    

    @GetMapping("/test2")
    public Integer test2() 
        System.out.println(1 / 0);
        return Integer.MAX_VALUE;
    
    

6. 测试

分别请求http://localhost:8080/test1、http://localhost:8080/test2,结果如下

在全局异常处理类中写了一行代码

log.error("全局异常信息:", e.getMessage());

所以调用test2方法时控制台打印异常信息如下

springboot如何统一后端返回格式?老鸟们都是这样玩的!

大家好,我是飘渺。今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常。首先我们来看看为什么要返回统一的标准格式?为什么要对SpringBoot返回统... 查看详情

springboot统一后端返回格式?老鸟们都是这样玩的!(代码片段)

大家好,我是bigsai。今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常。首先我们来看看为什么要返回统一的标准格式?为什么要对SpringBoot返回统... 查看详情

接口返回值response统一标准格式(代码片段)

一、为什么要对springboot的接口返回值统一标准格式  springboot默认情况下的response格式:String、Object、void、异常,以上几种情况,如果和客户端开发人员联调接口,他们会很懵逼,因为你给他们的接口没有一个统一的格式,客... 查看详情

springboot定义统一的返回json渲染格式(代码片段)

一 实操案例1.定义map类型packagecom.ljf.spring.boot.demo.common;importjava.util.LinkedHashMap;importjava.util.Map;/***@ClassName:R*@Description:TODO*@Author:liujianfu*@Date:2022/12/03 15:53:28 * 查看详情

springboot如何统一后端返回格式?老鸟们都是这样玩的!(代码片段)

...c;我是只爱教妹学Java的秃头哥。今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常。首先我们来看看为什么要返回统一的标准格式?为什么要对SpringBoot... 查看详情

springboot无侵入式实现api接口统一json格式返回(代码片段)

无侵入式 统一返回JSON格式其实本没有没打算写这篇博客的,但还是要写一下写这篇博客的起因是因为,现在呆着的这家公司居然没有统一的API返回格式?,询问主管他居然告诉我用HTTP状态码就够用了(fxxk)&#... 查看详情

springboot无侵入式实现api接口统一json格式返回(代码片段)

无侵入式 统一返回JSON格式其实本没有没打算写这篇博客的,但还是要写一下写这篇博客的起因是因为,现在呆着的这家公司居然没有统一的API返回格式?,询问主管他居然告诉我用HTTP状态码就够用了(fxxk)&#... 查看详情

springboot全局异常统一处理反参标准化

对于日常的开发过程中出现的异常,我把它分为两种,一种是需要给前端返回的异常,这种异常通常有入参格式、字段缺少、以及相关的业务异常,需要明确的告诉前端出现了什么问题,前端才好处理,而另一种异常例如空指针... 查看详情

springboot返回统一数据格式及其原理浅析

大家都知道,前后分离之后,后端响应最好以统一的格式的响应.譬如:名称描述  status状态码,标识请求成功与否,如[1:成功;-1:失败]  errorCode错误码,给出明确错误码,更好的应对业务异常;请求成功该值可为空&nbs... 查看详情

springboot定义统一的返回异常提示数据格式(代码片段)

一描述1.1没有加全局异常处理1.这里设置一个字符串为空指针异常,然后看看返回给前端的信息。 2.返回结果 3.效果看起来不友好的提示1.2 添加全局异常处理1.代码:添加一个全局异常处理类@ControllerAdvicepublicclassGlob... 查看详情

springmvc统一设置返回到前端的json时间格式

 我们在使用springmvc中的 @ResponseBody注解往前端返回JSON数据的时候发现时间总是一串数字,这里总结使用的两种解决时间格式问题的方法。1、在时间字段的get方法上使用注解@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss",timezone="GMT+8")这... 查看详情

每天用springboot,还不懂restfulapi返回统一数据格式是怎么实现的?

关于Spring的全局处理,我有两方面要说:统一数据返回格式统一异常处理为了将两个问题说明清楚,将分两个章节分别说明,本章主要说第一点有童鞋说,我们项目都做了这种处理,就是在每个API都单独工具类将返回值进行封装... 查看详情

springboot设置页面返回json的时间格式

一在springboot页面设置json中时间格式#设置返回json的全局时间格式spring.jackson.date-format=yyyy-MM-ddHH:mm:ssspring.jackson.time-zone=GMT+8 查看详情

springboot统一功能处理(用户登录权限效验-拦截器异常处理数据格式返回)(代码片段)

...格式返回的实现3.2@ControllerAdvice源码分析本篇将要学习SpringBoot统一功能处理模块,这也是AOP的实战环节统一用户登录权限的效验实现接口HandlerInterceptor+WebMvcConfigurer统一异常处理使用注解@RestControllerAdvice+@Excepti... 查看详情

asp.netapi(mvc)对app接口(json格式)接收数据与返回数据的统一管理

...,直接进入主题。需求:基于Http请求接收Json格式数据,返回Json格式的数据。整理:对接收的数据与返回数据进行统一的封装整理,方便处理接收与返回数据,并对数据进行验证,通过C#的特性对token进行验证,并通过时间戳的... 查看详情

springboot学习笔记:处理前端json返回的日期的格式

SpringBoot学习笔记(4):处理前端JSON返回的日期的格式问题描述  前端页面显示的时间为毫秒格式,不利于直观显示!解决方法1——后端解决publicclassFlow{@JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")privateDateflow_date;.....}解决方法2—... 查看详情

自定义统一api返回json格式(app后台框架搭建三)

...2,自定义一个注解,自己去解析对象成为json字符串进行返回第一种方式,我就不推荐,想弄得的话,可以自己去研究一下源码第二种方式,主要通过定义注解,通过 HandlerMethodReturnValueHandler对返回值的处理,而不让他进去vie... 查看详情

知识点-springboot统一异常处理汇总(代码片段)

...在实际开发中,我们会遇到很多异常,在发生异常的时候SpringBoot默认提供了错误页面展示给用户。看似比较友好,其实页面很丑。上面讲的是做页面开发的时候遇到的问题,还有一种情况就是用来开发Rest接口,当错误的时候我... 查看详情