设为首页 加入收藏

TOP

springboot优雅的统一返回格式 + 全局异常处理(包括404等异常)(一)
2023-08-26 21:10:50 】 浏览:75
Tags:springboot 全局异 常处理 包括 404

1.自定义枚举类

public enum ReturnCode {
    RC200(200, "ok"),
    RC400(400, "请求失败,参数错误,请检查后重试。"),
    RC404(404, "未找到您请求的资源。"),
    RC405(405, "请求方式错误,请检查后重试。"),
    RC500(500, "操作失败,服务器繁忙或服务器错误,请稍后再试。");

    // 自定义状态码
    private final int code;

    // 自定义描述
    private final String msg;

    ReturnCode(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

该枚举类为我们和前端约定好的返回状态码和描述信息,可根据自己的需求修改状态码和描述

2.自定义统一返回格式类

@Data
public class R<T> {

    private Integer code; //状态码

    private String msg; //提示信息

    private T data; //数据

    private long timestamp;//接口请求时间

    public R() {
        this.timestamp = System.currentTimeMillis();
    }

    public static <T> R<T> success(T data) {
        R<T> r = new R<>();
        r.setCode(ReturnCode.RC200.getCode());
        r.setMsg(ReturnCode.RC200.getMsg());
        r.setData(data);
        return r;
    }

    public static <T> R<T> error(int code, String msg) {
        R<T> r = new R<>();
        r.setCode(code);
        r.setMsg(msg);
        r.setData(null);
        return r;
    }
}

@Data注解为Lombok工具类库中的注解,提供类的get、set、equals、hashCode、canEqual、toString方法,使用时需配置Lombok,如不配置请手动生成相关方法。

我们返回的信息至少包括code、msg、data三部分,其中code是我们后端和前端约定好的状态码,msg为提示信息,data为返回的具体数据,没有返回数据则为null。除了这三部分外,你还可以定义一些其他字段,比如请求时间timestamp。

定义了统一返回类后,controller层返回数据时统一使用R.success()方法封装。

@RestController
@RequestMapping("/test")
public class TestController {
    @PostMapping("/test1")
    public R<List<Student>> getStudent() {
        ArrayList<Student> list = new ArrayList<>();
        Student student1 = new Student();
        student1.setId(1);
        student1.setName("name1");
        Student student2 = new Student();
        student2.setId(2);
        student2.setName("name2");
        list.add(student1);
        list.add(student2);
        return R.success(list);
    }
}

@Data
class Student {
    private Integer id;
    private String name;
}

例如在以上代码中,我们的需求是查询学生信息,我们调用这个test1接口就返回了以下的结果:

{
    "code": 200,
    "msg": "ok",
    "data": [
        {
            "id": 1,
            "name": "name1"
        },
        {
            "id": 2,
            "name": "name2"
        }
    ],
    "timestamp": 1692805971309
}

image-20230823235342116

到这里我们已经基本实现了统一返回格式,但是上面这种实现方式也有一个缺点,就是每次返回数据的时候都需要调用R.success()方法,非常麻烦,我们希望能够在controller层里直接返回我们实际的数据,即data字段中的内容,然后自动帮我们封装到R.success()之中,因此我们需要一种更高级的方法。

3.统一返回格式的高级实现

我们需要利用springboot的ResponseBodyAdvice类来实现这个功能,ResponseBodyAdvice的作用:拦截Controller方法的返回值,统一处理返回值/响应体

/**
 * 拦截controller返回值,封装后统一返回格式
 */
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<Object> {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        //如果Controller返回String的话,SpringBoot不会帮我们自动封装而直接返回,因此我们需要手动转换成json。
        if (o instanceof String) {
            return objectMapper.writeva lueAsString(R.success(o)
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇过滤器和拦截器的区别 下一篇Java Polymorphism Concept —— ..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目