Skip to content

全局统一返回对象

本系统定义了全局统一返回对象 R,返回给前端的格式为:

json
{
    "code": 0, // 状态码  0表示成功
    "msg": "", // 错误消息
    "path": "", // 请求的地址
    "timestamp": 0,  // 请求时的时间戳
    "data": {}, // 返回的业务数据
    "extra": {},  // 返回的扩展数据
}
{
    "code": 0, // 状态码  0表示成功
    "msg": "", // 错误消息
    "path": "", // 请求的地址
    "timestamp": 0,  // 请求时的时间戳
    "data": {}, // 返回的业务数据
    "extra": {},  // 返回的扩展数据
}

提示

我们可以在控制类的方法返回值上显示的使用 R 来包装返回值,也可以使用 AbstractGlobalResponseBodyAdvice 提供的全局包装器来优雅返回。

  1. 自己使用R来返回
java
@GetMapping("/check")
public R<Boolean> check(@RequestParam(required = false) Long id, @RequestParam String name) {
    return success(baseService.check(id, name));
}
@GetMapping("/check")
public R<Boolean> check(@RequestParam(required = false) Long id, @RequestParam String name) {
    return success(baseService.check(id, name));
}

返回值为:

json
{
    "code": 0, // 状态码  0表示成功
    "msg": "", // 错误消息
    "path": "", // 请求的地址
    "timestamp": 0,  // 请求时的时间戳
    "data": true, 
    "extra": {},  // 返回的扩展数据
}
{
    "code": 0, // 状态码  0表示成功
    "msg": "", // 错误消息
    "path": "", // 请求的地址
    "timestamp": 0,  // 请求时的时间戳
    "data": true, 
    "extra": {},  // 返回的扩展数据
}
  1. 使用全局包装器返回
java
// 控制类的方法,返回Boolean类型,也会统一包装成R的格式
@GetMapping("/check")
public Boolean check(@RequestParam(required = false) Long id, @RequestParam String name) {
    return baseService.check(id, name);
}
// 控制类的方法,返回Boolean类型,也会统一包装成R的格式
@GetMapping("/check")
public Boolean check(@RequestParam(required = false) Long id, @RequestParam String name) {
    return baseService.check(id, name);
}

返回值为:

json
{
    "code": 0, // 状态码  0表示成功
    "msg": "", // 错误消息
    "path": "", // 请求的地址
    "timestamp": 0,  // 请求时的时间戳
    "data": true, 
    "extra": {},  // 返回的扩展数据
}
{
    "code": 0, // 状态码  0表示成功
    "msg": "", // 错误消息
    "path": "", // 请求的地址
    "timestamp": 0,  // 请求时的时间戳
    "data": true, 
    "extra": {},  // 返回的扩展数据
}

全局响应体包装, 实现代码:

  • 定义全局响应包装器
java
public class AbstractGlobalResponseBodyAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        // 类上如果被 IgnoreResponseBodyAdvice 标识就不拦截
        if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseBodyAdvice.class)) {
            return false;
        }

        // 方法上被标注也不拦截
        if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseBodyAdvice.class)) {
            return false;
        }
        return true;
    }

  	// 主要代码看这里
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (o == null) {
            return null;
        }
        if (o instanceof R) {
            return o;
        }

        return R.success(o);
    }
}
public class AbstractGlobalResponseBodyAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        // 类上如果被 IgnoreResponseBodyAdvice 标识就不拦截
        if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseBodyAdvice.class)) {
            return false;
        }

        // 方法上被标注也不拦截
        if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseBodyAdvice.class)) {
            return false;
        }
        return true;
    }

  	// 主要代码看这里
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (o == null) {
            return null;
        }
        if (o instanceof R) {
            return o;
        }

        return R.success(o);
    }
}
  • 在需要此功能的服务,新建ResponseConfiguration,并继承 AbstractGlobalResponseBodyAdvice:
java
@Configuration
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@RestControllerAdvice(basePackages = {"top.acuity.box"})
public class ResponseConfiguration extends AbstractGlobalResponseBodyAdvice {
}
@Configuration
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@RestControllerAdvice(basePackages = {"top.acuity.box"})
public class ResponseConfiguration extends AbstractGlobalResponseBodyAdvice {
}
  • 若您配置了ResponseConfiguration类,但某些接口不希望按照 R 的格式返回,可以在方法或类上加 @IgnoreResponseBodyAdvice 来禁用此功能。
java
@GetMapping("/check")
// 若不加@IgnoreResponseBodyAdvice 注解,返回值依然是 R 的格式
@IgnoreResponseBodyAdvice
public Boolean check(@RequestParam(required = false) Long id, @RequestParam String name) {
    return success(baseService.check(id, name));
}
@GetMapping("/check")
// 若不加@IgnoreResponseBodyAdvice 注解,返回值依然是 R 的格式
@IgnoreResponseBodyAdvice
public Boolean check(@RequestParam(required = false) Long id, @RequestParam String name) {
    return success(baseService.check(id, name));
}

返回值为:

java
true
true

欢迎使用天源云Saas快速开发系统