SpringBoot定义优雅全局统一Restful API 响应框架完结撒花篇封装starter组件

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: SpringBoot定义优雅全局统一Restful API 响应框架完结撒花篇封装starter组件

之前我们已经,出了一些列文章。 讲解如何封统一全局响应Restful API。

感兴趣的可以看我前面几篇文章 (整个starter项目发展史)

SpringBoot定义优雅全局统一Restful API 响应框架

SpringBoot定义优雅全局统一Restful API 响应框架二

SpringBoot定义优雅全局统一Restful API 响应框架三

SpringBoot定义优雅全局统一Restful API 响应框架四

SpringBoot定义优雅全局统一Restful API 响应框架五

SpringBoot定义优雅全局统一Restful API 响应框架六

后续我萌生里新的想法,SpringBoot 不是提供了自己的starter。我们也可以自定义starter吗,于是我定义了rest-api-spring-boot-starter,已经发布到maven中央仓库,对之前Restful API 响应框架 做了集成和重构,

在这个基础上我又总结封装了我自己工作以常用的很多工具,结合SpringBoot 封装了全能的工具。 已经更新到了1.3.0 不耦合任何依赖 请使用最新版本

目前更新版本1.3.0 功能如下

  1. 支持一键配置自定义RestFull API 统一格式返回
  2. 支持RestFull API 错误国际化
  3. 支持全局异常处理,全局参数验证处理
  4. 业务错误断言工具封装,遵循错误优先返回原则
  5. redis工作封装。支持所有key操作工具
  6. RestTemplate 封装 POST,GET 请求工具
  7. 日志集成。自定义日志路径,按照日志等级分类,支持压缩和文件大小分割。按时间显示
  8. 工具库集成 集成了lombok,hutool,commons-lang3,guava。不需要自己单个引入
  9. 集成mybatisPlus一键代码生成

github 地址

下面我讲一下怎么在项目中去使用

我们新建一个SpringBoot Web项目

我们只需要在pom中引入即可

 <dependency>
            <groupId>cn.soboys</groupId>
            <artifactId>rest-api-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

在启动类或者配置类中加上@EnableRestFullApi 注解即可

RestFull API使用

这样在项目controller中我们写普通的请求如:

 @PostMapping("/chat")
    public HashMap chatDialogue() {
   
   
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

返回的就是全局统一RestFull API

我们也可以这么写

提供了很多返回方法。

当然如果你这个接口不想包装成全局返回,想自定义单独返回 如我们只需要在方法上加上@NoRestFulApi 注解即可

   @PostMapping("/chat")
    @NoRestFulApi
    public HashMap chatDialogue() {
   
   
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

就不会对返回内容进行任何包装处理。

全局错误拦截,参数校验

帮你封装好了所有http常见错误,和所有请求类型和参数错误。

如请求错误

{
   
   
    "success": false,
    "code": "405",
    "msg": "方法不被允许",
    "timestamp": "2023-07-03 22:36:47",
    "data": "Request method 'GET' not supported"
}

请求资源不存在

{
   
   
    "success": false,
    "code": "404",
    "msg": "请求资源不存在",
    "timestamp": "2023-07-03 22:42:35",
    "data": "/api"
}

参数校验错误

验证Studen对象参数

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/6/26 22:10
 * @webSite https://github.com/coder-amiao
 */
@Data
public class Student {
   
   
    @NotBlank
    private String nam;
    @NotBlank
    private String hobby;
}
    @PostMapping("/chat")
    public HashMap chatDialogue(@Validated  Student student) {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

请求结果

JSON Body参数

    @PostMapping("/chat")
    public HashMap chatDialogue(@RequestBody @Validated  Student student) {
   
   
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

错误国际化

内置封装错误默认支持英文和中文两种国际化。你不做任何配置自动支持

如果需要内置支持更多语言,覆盖即可。

自定义自己错误国际化和语言

  i18n:
    # 若前端无header传参则返回中文信息
    i18n-header: Lang
    default-lang: cn
    message:
      # admin
      internal_server_error:
        en: Internal Server Error
        cn: 系统错误
      not_found:
        en: Not Found
        cn: 请求资源不存在

message 对应错误提示
对应internal_server_error 自定义
下面语言自己定义 和前端传入i18n-header 对应上,就显你定义错误语言

我不传错误国际化默认就是中文在 default-lang: cn
进行配置

当我传入 指定语言 就会按照你配置的国际化自定义返回错误提示

自定义错误响应

如果我内置错误无法满足你业务需求,你也可以自定义自己错误码

你自定义错误枚举 只需要实现ResultCode接口即可

package cn.soboys.restapispringbootstarter;

import cn.soboys.restapispringbootstarter.i18n.I18NKey;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/6/26 10:21
 * @webSite https://github.com/coder-amiao
 * 响应码接口,自定义响应码,实现此接口
 */
public interface ResultCode extends I18NKey {
   
   

    String getCode();

    String getMessage();

}
`

如果要支持国际化还需要实现国际化接口I18NKey 参考我内部HttpStatus实现即可

package cn.soboys.restapispringbootstarter;

import cn.soboys.restapispringbootstarter.i18n.I18NKey;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/6/26 11:01
 * @webSite https://github.com/coder-amiao
 */
public enum HttpStatus implements ResultCode, I18NKey {
   
   
    /**
     * 系统内部错误
     */
    INTERNAL_SERVER_ERROR("500", "internal_server_error"),
    BAD_GATEWAY("502", "bad_gateway"),
    NOT_FOUND("404", "not_found"),
    UNAUTHORIZED("401", "unauthorized"),
    FORBIDDEN("403", "forbidden"),
    METHOD_NOT_ALLOWED("405", "method_not_allowed"),
    REQUEST_TIMEOUT("408", "request_timeout"),

    INVALID_ARGUMENT("10000", "invalid_argument"),
    ARGUMENT_ANALYZE("10001", "argument_analyze"),
    BUSINESS_EXCEPTION("20000", "business_exception");


    private final String value;

    private final String message;

    HttpStatus(String value, String message) {
   
   
        this.value = value;
        this.message = message;
    }


    @Override
    public String getCode() {
   
   
        return value;
    }

    @Override
    public String getMessage() {
   
   
        return message;
    }


    @Override
    public String key() {
   
   
        return message;
    }
}
rest-api:
  enabled: false
  i18n:
    # 若前端无header传参则返回中文信息
    i18n-header: Lang
    default-lang: cn
    message:
      # admin
      internal_server_error:
        en: Internal Server Error
        cn: 系统错误
      bad_gateway:
        en: Bad Gateway
        cn: 错误的请求
      unauthorized:
        en: Unauthorized
        cn: 未授权
      forbidden:
        en: Forbidden
        cn: 资源禁止访问
      method_not_allowed:
        en: Method Not Allowed
        cn: 方法不被允许
      request_timeout:
        en: Request Timeout
        cn: 请求超时
      invalid_argument:
        en: Invalid Argument {
   
   }
        cn: 参数错误 {
   
   }
      argument_analyze:
        en: Argument Analyze {
   
   }
        cn: 参数解析异常 {
   
   }
      business_exception:
        en: Business Exception
        cn: 业务错误
      not_found:
        en: Not Found
        cn: 请求资源不存在

内部错误不需要做任何配置,自动支持国际化。如果需要支持更多语言,可以自定义进行覆盖。

业务异常断言

在项目开发中我们有时需要封装自己异常类,信息我封装了统一的错误异常类。
BusinessException 对业务异常类做了全局错误拦截,

封装·了统一业务异常断言工具,遵循错误优先返回原则。代码更优雅

    @GetMapping("/exception")
    public Result exception(){
   
   
        Student s=null;
        Assert.isFalse(s==null,"学生不能为空");
        return Result.buildSuccess();
    }

抛出统一业务异常

当然如果你要定义自己的异常类。可以定义自己异常类·继承我的BusinessException

Redis 工具库使用

进一步封装的对Redis所以相关key,value操作,在使用redis工具库时候。我们需要引入

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

默认不会帮你引入。

然后在使用时候注入就行

@Autowired
    private RedisTempUtil redisTempUtil;

    @GetMapping("/redis")
    public Result redis() {
   
   
        redisTempUtil.set("test", "123456");
        return Result.buildSuccess();
    }


    @GetMapping("/redis/get")
    public Result redisGet() {
   
   
        String value = redisTempUtil.get("test").toString();
        log.info("redis值{}", value);
        return Result.buildSuccess();
    }

RestTemplate 请求工具

进一步封装了RestTemplate请求 Post和GET
项目中使用时注入

 @Autowired
    private RestFulTemp restFulTemp;

    @GetMapping("/doGet")
    public Result doGet() {
   
   
        ResponseEntity<String> response = restFulTemp.doGet("http://127.0.0.1:8000/redis/get");
        return Result.buildSuccess(response.getBody());
    }

日志使用

进一步封装了 日志处理达到开箱即用。在属性文件中配置相关日志配置即可

rest-api:
  enabled: false
  logging:
    path: ./logs   #日志存储路径(服务器上绝对)
    max-history: 90 # 保存多少天
    max-file-size: 3MB  # 每个文件大小
    max-total-size-cap: 1GB  #总文件大小超过多少压缩
    level-root: INFO    # 这里的INFO可以替换为其他日志等级,如DEBUG, WARN, ERROR, TRACE, FATAL, OFF等。 日志等级由低到高分别是debugger-info-warn-error

如果你的属性文件不做任何日志配置,默认日志就是上面这样配置。

集成mybatisPlus一键代码生成

在项目中我们会频繁使用到mybatisPlus 但是简单的模板代码我们一键生成就好。 默认不依赖mybatisPlus任何相关包。如果需要使用自动代码生成引入mybatisPlus 代码生成依赖包即可。

 <!--生成器依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
            <optional>true</optional>
        </dependency>
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
            <optional>true</optional>
        </dependency>
        <!--代码生成依赖的模板引擎-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
            <optional>true</optional>
        </dependency>

你可以直接写测试类,然后直接去调用代码生成即可

public class Test {
   
   
    public static void main(String[] args) {
   
   
        GenerateCodeConfig config=new GenerateCodeConfig();
        config.setDriverName("com.mysql.cj.jdbc.Driver");
        config.setUsername("root");
        config.setPassword("root");
        config.setUrl("jdbc:mysql://127.0.0.1:3306/ry?useUnicode=true&useSSL=false&characterEncoding=utf8");
        //生成代码保存路径,不设置就是当前项目下路径,如何设置请使用绝对路径
        config.setProjectPath("superaide");
        config.setPackages("cn.soboys.superaide");
        MyBatisPlusGenerator.generate(config);
    }
}

效果如下

关注公众号,程序员三时 持续输出优质内容 希望给你带来一点启发和帮助

下篇文章就这个源码剖析讲解 如何封装自己的stater

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
17天前
|
JSON 算法 安全
探索RESTful API设计的最佳实践
【9月更文挑战第2天】在数字化时代的浪潮中,后端开发如同搭建一座桥梁,连接着用户与数据的无限可能。本文将深入探讨如何打造高效、可维护的RESTful API,从资源命名到状态码的巧妙运用,每一个细节都隐藏着提升用户体验的智慧。你将学会如何在浩瀚的代码海洋中,用简洁明了的设计原则,引领用户安全抵达数据的彼岸。让我们一起启航,探索API设计的奥秘,让后端开发成为艺术与科学的完美结合。
|
16天前
|
缓存 JavaScript 前端开发
深入浅出:使用Node.js构建RESTful API
【9月更文挑战第3天】在数字化浪潮中,后端开发如同搭建一座连接用户与数据的桥梁。本文将带领读者从零开始,一步步用Node.js搭建一个功能完备的RESTful API。我们将探索如何设计API的结构、处理HTTP请求以及实现数据的CRUD操作,最终通过一个简单的实例,展示如何在真实世界中应用这些知识。无论你是初学者还是有一定经验的开发者,这篇文章都会为你揭示后端开发的奥秘,让你轻松入门并掌握这一技能。
40 3
|
6天前
|
JSON 前端开发 API
打造高效后端:RESTful API 设计的最佳实践
【9月更文挑战第14天】在数字化时代,后端开发是构建强大、灵活和可维护应用程序的基石。本文将深入探讨如何设计高效的RESTful API,包括清晰的资源定义、合理的HTTP方法使用、URL结构规划、状态码的准确返回以及数据格式的设计。通过这些实践,开发者能够创建出既符合行业标准又易于维护和扩展的API,为前端提供强大的数据支持,确保整个应用的稳定性和性能。
139 74
|
6天前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
6天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
6天前
|
XML API 开发者
掌握RESTful API设计的艺术
【9月更文挑战第14天】在数字化时代,APIs如同一座座桥梁,连接着不同的软件系统和服务。本文将深入探讨如何设计高效、可维护且易于理解的RESTful API,同时提供实际代码示例,帮助开发者构建更加稳固和灵活的后端服务。
29 11
|
9天前
|
Go API 开发者
深入探讨:使用Go语言构建高性能RESTful API服务
在本文中,我们将探索Go语言在构建高效、可靠的RESTful API服务中的独特优势。通过实际案例分析,我们将展示Go如何通过其并发模型、简洁的语法和内置的http包,成为现代后端服务开发的有力工具。
|
2天前
|
API 网络架构 开发者
探索后端开发:RESTful API设计的艺术
【9月更文挑战第18天】在数字化时代的浪潮中,后端开发如同搭建一座座坚固的桥梁,连接用户与数据的无限可能。本文将深入浅出地探讨RESTful API设计的精髓,从理论基础到实践应用,带领读者领略API设计的艺术。我们将以代码示例为灯塔,照亮理解之路,但
|
2天前
|
Java 应用服务中间件 开发者
深入探索并实践Spring Boot框架
深入探索并实践Spring Boot框架
13 2
|
1天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应