Springboot项目中如何设计一个规范的统一的Restful API 响应框架?

简介: Springboot项目中如何设计一个规范的统一的Restful API 响应框架?

一、设计

目前项目开发,都是基于前后端分离模式开发的,基于后端模板引擎那一套,可能已经不适用一些项目开发流程,和当下开发模式了,尤其在要写比较大型项目,前后端项目拆分,团队共同开发那是必不可少的

目前的前后端开发大部分数据的传输格式都是json,因此定义一个统一规范的数据格式有利于前后端的交互与UI的展示。

返回的统一接口形式应该包含这些内容

  1. 是否响应成功
  2. 响应状态码
  3. 状态码描述
  4. 响应数据
  5. 接口调用时间
  6. 其他标识符

按照这些我们可以定义统一的标准结果返回

二、响应枚举

前三者可以定义为 success,code,message

package com.tigerhhzz.springbootmybatisplusdemo.domain;
import lombok.Getter;
/**
 * @author tigerhhzz
 * @date 2023/5/10 9:28
 * 响应结果枚举
 */
@Getter
public enum ResultCodeEnum {
    SUCCESS(true, 200, "成功"),
    FAIL(false, 400, "请求失败"),
    NOT_FOUND(false, 404, "接口不存在"),
    FORBIDDEN(false, 403, "资源拒绝访问"),
    UNAUTHORIZED(false, 401, "未认证(签名错误)"),
    INTERNAL_SERVER_ERROR(false, 500, "服务器内部错误"),
    NULL_POINT(false, 200002, "空指针异常"),
    PARAM_ERROR(false, 200001, "参数错误");
    /**
     * 响应是否成功
     */
    private Boolean success;
    /**
     * 响应状态码
     */
    private Integer code;
    /**
     * 响应信息
     */
    private String message;
    ResultCodeEnum(Boolean success, Integer code, String message) {
        this.success = success;
        this.code = code;
        this.message = message;
    }
}

三、统一结果类

  • 外部返回调用类统一的结果方法 success,failure 因此构造器私有
  • 内置静态方法,直接返回对象
  • 便于自定义统一结果信息,使用链式编程,返回对象类本身 return this
  • 响应数据为json格式,可定义为JsonObject或Map形式
package com.tigerhhzz.springbootmybatisplusdemo.domain;
import java.util.HashMap;
import java.util.Map;
/**
 * @author tigerhhzz
 * @date 2023/5/10 9:31
 * 统一响应结果处理  使用链式编程 返回类本身
 */
public class CommonRespResult {
    private Boolean success;
    private Integer code;
    private String message;
    /**
     * 接口请求时间戳
     */
    private Long timestamp;
    private Map<String, Object> data = new HashMap<>();
    private CommonRespResult setSuccess(Boolean success) {
        this.success = success;
        return this;
    }
    private CommonRespResult setMessage(String message) {
        this.message = message;
        return this;
    }
    private CommonRespResult setData(Map<String, Object> data) {
        this.data = data;
        return this;
    }
    private CommonRespResult setCode(Integer code) {
        this.code = code;
        return this;
    }
    private CommonRespResult() {
    }
    private CommonRespResult(Long timestamp) {
        this.timestamp = timestamp;
    }
    /**
     * 通用返回成功
     *
     * @return
     */
    public static CommonRespResult success() {
        return new CommonRespResult(System.currentTimeMillis())
                .setSuccess(ResultCodeEnum.SUCCESS.getSuccess())
                .setCode(ResultCodeEnum.SUCCESS.getCode())
                .setMessage(ResultCodeEnum.SUCCESS.getMessage());
    }
    /**
     * 通用返回失败
     *
     * @return
     */
    public static CommonRespResult failure() {
        return new CommonRespResult(System.currentTimeMillis())
                .setSuccess(ResultCodeEnum.FAIL.getSuccess())
                .setCode(ResultCodeEnum.FAIL.getCode())
                .setMessage(ResultCodeEnum.FAIL.getMessage());
    }
    /**
     * 设置结果,形参为结果枚举
     *
     * @param result
     * @return
     */
    public static CommonRespResult setResult(ResultCodeEnum result) {
        return new CommonRespResult(System.currentTimeMillis())
                .setSuccess(result.getSuccess())
                .setCode(result.getCode())
                .setMessage(result.getMessage());
    }
    // 自定义返回数据
    public CommonRespResult data(Map<String, Object> map) {
        return this.setData(map);
    }
    // 通用设置data
    public CommonRespResult data(String key, Object value) {
        this.data.put(key, value);
        return this;
    }
    // 自定义状态信息
    public CommonRespResult message(String message) {
        return this.setMessage(message);
    }
    // 自定义状态码
    public CommonRespResult code(Integer code) {
        return this.setCode(code);
    }
    // 自定义返回结果
    public CommonRespResult success(Boolean success) {
        return this.setSuccess(success);
    }
}

四、控制层调用返回

package com.tigerhhzz.springbootmybatisplusdemo.controller;
import com.tigerhhzz.springbootmybatisplusdemo.domain.CommonRespResult;
import com.tigerhhzz.springbootmybatisplusdemo.domain.MBlog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author tigerhhzz
 * @since 2023-04-28
 */
@RestController
public class MBlogController {
    @GetMapping("/index")
    public CommonRespResult index() {
        Map m = new HashMap();
        m.put("name", "Tom");
        m.put("age", 25);
        m.put("sex", "男");
        return CommonRespResult.success().data(m);
    }
    @GetMapping("/home")
    public CommonRespResult home() {
        MBlog mBlog = new MBlog();
        mBlog.setContent("DFSDFSDFSDFSD");
        mBlog.setTitle("FFDSFD");
        return CommonRespResult.success().data("mBlog",mBlog).message("查询用户详情信息");
    }
    /**
     * 异常返回模拟
     *
     * @return
     */
    @GetMapping("/exception")
    public CommonRespResult exception() {
        Map m = null;
        m.put("name", "Jack");
        return CommonRespResult.success().data("user", m).message("查询用户详情信息");
    }
}

统一结果类的使用参考了mybatis-plus中Result对象的设计。

目录
打赏
0
1
1
0
36
分享
相关文章
微服务——SpringBoot使用归纳——Spring Boot开发环境搭建和项目启动
本文介绍了Spring Boot开发环境的搭建和项目启动流程。主要内容包括:jdk的配置(IDEA、STS/eclipse设置方法)、Spring Boot工程的构建方式(IDEA快速构建、官方构建工具start.spring.io使用)、maven配置(本地maven路径与阿里云镜像设置)以及编码配置(IDEA和eclipse中的编码设置)。通过这些步骤,帮助开发者顺利完成Spring Boot项目的初始化和运行准备。
17 0
微服务——SpringBoot使用归纳——Spring Boot开发环境搭建和项目启动
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
72 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
ai-api-union项目,适配各AI厂商api
本项目旨在实现兼容各大模型厂商API的流式对话和同步对话接口,现已支持智谱、豆包、通义、通义版DeepSeek。项目地址:[https://gitee.com/alpbeta/ai-api-union](https://gitee.com/alpbeta/ai-api-union)。通过`ChatController`类暴露两个接口,入参为`ChatRequest`,包含会话ID、大模型标识符和聊天消息列表。流式对话返回`Flux&lt;String&gt;`,同步调用返回`String`
88 2
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
15 0
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
在微服务架构中,随着业务复杂度增加,项目可能需要调用多个微服务。为避免使用`@Value`注解逐一引入配置的繁琐,可通过定义配置类(如`MicroServiceUrl`)并结合`@ConfigurationProperties`注解实现批量管理。此方法需在配置文件中设置微服务地址(如订单、用户、购物车服务),并通过`@Component`将配置类纳入Spring容器。最后,在Controller中通过`@Resource`注入配置类即可便捷使用,提升代码可维护性。
13 0
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
11 0
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——使用Logger在项目中打印日志
本文介绍了如何在项目中使用Logger打印日志。通过SLF4J和Logback,可设置不同日志级别(如DEBUG、INFO、WARN、ERROR)并支持占位符输出动态信息。示例代码展示了日志在控制器中的应用,说明了日志配置对问题排查的重要性。附课程源码下载链接供实践参考。
18 0
SpringBoot项目打包成war包
通过上述步骤,我们成功地将一个Spring Boot应用打包成WAR文件,并部署到外部的Tomcat服务器中。这种方式适用于需要与传统Servlet容器集成的场景。
48 8
DeepSeek-Free-API:DeepSeekV3免费的api接口,需要使用api方式的同学可以参考一下这个项目,可以收藏起来试一下
嗨,大家好,我是小华同学。今天为大家介绍一个开源项目——DeepSeek V3 Free 服务。该项目基于 DeepSeek-V3 R1 大模型,提供免费、高性能的 API,支持高速流式输出、多轮对话、联网搜索和深度思考等功能。适用于智能客服、内容创作、教育辅助等场景。部署方式灵活,支持 Docker、Docker-compose、Render、Vercel 和原生部署。欢迎关注我们,获取更多优质开源项目和高效工作学习方法。
683 15
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。