秒懂SpringBoot之如何集成SpringDoc(全网目前最新最系统最全面的springdoc教程)

news2024/9/22 5:41:18

[版权申明] 非商业目的注明出处可自由转载
出自:shusheng007

文章目录

  • 概述
  • 概念解释
  • SpringDoc使用
    • 简单集成
    • 配置文档信息
    • 配置文档分组
    • 使用注解
      • `@Tag`
      • `@Operation`
      • `@Schema`
      • `@Parameter`
      • `@Parameters`
      • `@ApiResponses` 和`@ApiResponse`
    • 认证授权
      • 无需认证
      • 需要认证
  • 总结
  • 源码

概述

近来颇为懈怠,博客竟两月有余未发一篇,惭愧惭愧。值此端午佳节(dragon boat festival)作为调包高手、API小王子的我就聊聊API文档的那些事吧,如果你也是API小王子,那我们就可以在一起欢度佳节了,哈哈…

我惯用Java,惯用Spring,所以这里谈论的是关于springboot中如何处理文档的内容

概念解释

谈到API文档,那就绕不开大名鼎鼎的Swagger,但是你是否还听说过:OpenAPISpringfoxSpringdoc?你第一次看到这些脑瓜子是不是嗡嗡的?

  • OpenAPI

是一个组织(OpenAPI Initiative),他们指定了一个如何描述HTTP API的规范(OpenAPI Specification)。既然是规范,那么谁想实现都可以,只要符合规范即可。

  • Swagger

它是SmartBear这个公司的一个开源项目,里面提供了一系列工具,包括著名的 swagger-uiswagger是早于OpenApi的,某一天swagger将自己的API设计贡献给了OpenApi,然后由其标准化了。

  • Springfox

是Spring生态的一个开源库,是Swagger与OpenApi规范的具体实现。我们使用它就可以在spring中生成API文档。以前基本上是行业标准,目前最新版本可以支持 Swagger2, Swagger3 以及 OpenAPI3 三种格式。但是其从 2020年7月14号就不再更新了,不支持springboot3,所以业界都在不断的转向我们今天要谈论的另一个库Springdoc,新项目就不要用了。

  • Springdoc

算是后起之秀,带着继任Springfox的使命而来。其支持OpenApi规范,支持Springboot3,我们的新项目都应该使用这个。

SpringDoc使用

我们可以在springboot中使用SpringDoc来生成API文档,详情可以参考官网,下面我们来简单的实践一下。

简单集成

在springboot中使用springdoc起步非常容易,只需要引入其starter即可

<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-ui</artifactId>
   <version>1.7.0</version>
</dependency>

运行后访问下面的链接即可

http://server:port/context-path/swagger-ui.html 

例如

http://localhost:8080/swagger-ui.html 

例如我们有如下代码:

@RestController
@RequestMapping("/api/programmer")
public class ProgrammerController {
    @PostMapping()
    public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {
        return new Programmer(1, request.getAge(), request.getProgrammingLang());
    }

    @GetMapping("/{id}")
    public Programmer getProgrammer(@PathVariable Integer id) {
        return new Programmer(1, 35, List.of("Java,Python,SQL"));
    }
}

添加依赖运行后访问http://localhost:8080/swagger-ui.html后结果如下

在这里插入图片描述

是不是特牛逼?当然springdoc的集成不可能就这点东西,不然也没有这篇文章了,咱接着往下看。苦于网上的一些教程不直观,对初学者不友好,所以本文以代码和其效果的形式来展示,保你一看就会。

配置文档信息

得益于springboot的强大,我们只需添加一个依赖就可以使用API文档了,但是使用的都是默认值,我们当然也希望对其进行各种自定义的配置

  • 配置文档信息

创建一个OpenAPI 的bean,配置文档名称等信息

@Configuration
public class SpringDocConfig {
    @Bean
    public OpenAPI myOpenAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("程序员API")
                        .description("程序员的大本营")
                        .version("v1.0.0")
                        .license(new License()
                                .name("许可协议")
                                .url("https://shusheng007.top"))
                        .contact(new Contact()
                                .name("书生007")
                                .email("wangben850115@gmail.com")))
                .externalDocs(new ExternalDocumentation()
                        .description("ShuSheng007博客")
                        .url("https://shusheng007.top"));
    }
 }

效果:

在这里插入图片描述
里面的配置项很多,可以根据代码和截图对照一下,按照自己的需求配置即可

配置文档分组

用来配置分组的,假如你有两类controller一类以/api为前缀,一类以/admin为前缀,就可以将其配置为两个分组。很多时候我们只有一个分组,所以就不需要下面的配置。

@Configuration
public class SpringDocConfig {
   ...
    @Bean
    public GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
                .group("api")
                .pathsToMatch("/api/**")
                .build();
    }

    @Bean
    public GroupedOpenApi adminApi() {
        return GroupedOpenApi.builder()
                .group("admin")
                .pathsToMatch("/admin/**")
                .build();
    }
}

效果:

在这里插入图片描述
可以通过右上角的下拉框选择要展示的group。

使用注解

这个是咱们的重头戏,OpenApi 规范提供了很多注解,下面是一些常用的

注解含义
@Tag用在controller类上,描述此controller的信息
@Operation用在controller的方法里,描述此api的信息
@Parameter用在controller方法里的参数上,描述参数信息
@Parameters用在controller方法里的参数上
@Schema用于Entity,以及Entity的属性上
@ApiResponse用在controller方法的返回值上
@ApiResponses用在controller方法的返回值上
@Hidden用在各种地方,用于隐藏其api

下面我们一起来看看效果

@Tag

@Tag(name = "程序员", description = "程序员乐园")
@RestController
@RequestMapping("/api/programmer")
public class ProgrammerController {
...
}

效果

在这里插入图片描述

@Operation

@Operation(summary = "创建程序员", description = "用于创建一个闷骚的程序员")
@PostMapping()
public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {
    return new Programmer(666, "王二狗", request.getAge(), request.getProgrammingLang());
}

效果
在这里插入图片描述
@Operation 其实很复杂的,我们可以将下面要将的@Parameter以及@ApiResponse都可以配置在它里面。

@Schema

@Schema 用于实体类和其属性,例如有如下代码:

@Schema(description = "创建程序员入参")
public class CreateProgrammerRequest {

    @Schema(description = "名称", example = "王二狗")
    private String name;

    @Schema(description = "年龄", example = "35")
    private Integer age;

    @Schema(description = "掌握的编程语言", type = "List", example = "[\"Java\",\"Sql\"]")
    private List<String> programmingLang;
}

效果:

在这里插入图片描述
还可以切换到 Schema选项进行查看

在这里插入图片描述
同时,Springdoc还支持 Java Bean Validation API 的注解,例如@NotNull

@Schema(description = "创建程序员入参")
public class CreateProgrammerRequest {

    @NotNull
    @Schema(description = "名称", example = "王二狗")
    private String name;

    @NotNull
    @Min(18)
    @Max(35)
    @Schema(description = "年龄", example = "35")
    private Integer age;
  ...
}

效果:

在这里插入图片描述
注意红框中的内容,name和age右上角都有出现了一个红色的星星,表示是必填的。age也被限制了范围。

@Parameter

用于添加接口参数信息

@GetMapping("/{id}")
public Programmer getProgrammer(@Parameter(description = "程序员id") @PathVariable Integer id) {
    ...
}

效果

在这里插入图片描述

@Parameters

@Parameter作用一样,但是可以批量添加,不用一个一个的写在参数前面

@Parameters(value = {
        @Parameter(name = "name", description = "姓名", in = ParameterIn.PATH),
        @Parameter(name = "age", description = "年龄", in = ParameterIn.QUERY)
})
@GetMapping("/{name}")
public List<Programmer> getProgrammers(@PathVariable("name") String name, @RequestParam("age") Integer age) { 
    ...
}

parameters里的parameter使用name来找到方法中的入参,这块要对应上。

效果:

在这里插入图片描述

@ApiResponses@ApiResponse

顾名思义,此注解用来描述返回值的。

    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "成功",
                    content = {@Content(mediaType = "application/json",
                            schema = @Schema(implementation = Programmer.class))}),
            @ApiResponse(responseCode = "405", description = "非法输入",
                    content = @Content)
    })
    @PostMapping()
    public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {
       ...
    }

效果

在这里插入图片描述
可见,我们成功配置了两种情况的返回值。但是我们一般不会手动给每个API 写上一堆 @ApiResponse,那的多烦啊。业界通常会有一个统一的返回类型,例如

public class Result<T> implements Serializable {
    private int code;
    private String message;
    private T data;
    private String traceId;
}

还会有一个统一的异常处理类,使用@RestControllerAdvice标记,然后每个方法会捕捉对应的异常,只要我们使用@ResponseStatus来标记这些方法,springdoc就会自动生成相应的文档

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleException(HttpServletRequest httpServletRequest, Exception e) {
        return new Result(StatusCode.FAILED.getCode(), StatusCode.FAILED.getMessage(), null);
    }

    @ExceptionHandler(value = ApiException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result handleBusinessException(HttpServletRequest httpServletRequest, ApiException e) {
        return new Result(e.getCode(), e.getMessage(), null);
    }
}

例如我们有如下代码:

...
@RequestMapping(value = "/api/programmer",produces =  "application/json")
public class ProgrammerController {

    @GetMapping("/{id}")
    public Result<Programmer> getProgrammer(@Parameter(description = "程序员id") @PathVariable Integer id) {
        ...
    }
}

生成的api文档如下:

在这里插入图片描述
可见,多了400和500。

认证授权

我们知道swagger-ui不仅可以看API文档也可以直接调用API,这点很牛逼。但有时我们的服务需要认证,否则就调用不通,那怎么办?稍安勿躁,OpenApi规范也考虑到了这个问题。

OpenAPI 3.0 支持下面的认证模式:

  • HTTP authentication schemes (使用Authorization header):
    • Basic
    • Bearer
    • Other HTTP schemes as defined by RFC 7235 and HTTP Authentication Scheme Registry
  • API keys in headers, query string or cookies
    • Cookie authentication
  • OAuth 2
  • OpenID Connect Discovery

有的我也没用过,我们常用的就是Http Auth,以及OAuth2。本文以HTTP Bearer来作为我们服务的认证授权模式,如下图所示。

在这里插入图片描述

无需认证

当你的服务没有认证机制的话是可以直接调用的:

每个API 右上角都有一个try it out按钮,点击输入参数点击execute按钮即可,如下所示。

在这里插入图片描述

需要认证

如果你的服务需要认证后才能调用,那么默认情况下就不行了。例如你使用了Spring Security,或者你自己写了个Filter 来实现认证功能。

下面是demo服务用来做认证的Filter,采用HTTP Bearer 模式。所以需要在请求的Authentication Header 里 携带token 123才能通过认证。

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
   ...
    @Override
    protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
    ...

        // get token from header [Authorization: Bearer <token>]
        String authHeader = request.getHeader(AUTH_HEADER);
        ...

        String authToken = authHeader.split(" ")[1];
        if (!"123".equals(authToken)) {
            genUnauthResponse(response);
            return;
        }
        filterChain.doFilter(request, response);
    }

所以当从swagger-ui上调用API时,返回了401,如下图所示。那怎么才能正常调用API呢?接下来让我们看一下

在这里插入图片描述
Springdoc 使用@SecurityScheme 来定义一个安全模式,我们可以定义全局的,也可以针对某个controller定义类级别的,我们这里定义一个全局的。

  1. 在Application类上添加@SecurityScheme
@SecurityScheme(name = "api_token", type = SecuritySchemeType.HTTP, scheme ="bearer", in = SecuritySchemeIn.HEADER)
@SpringBootApplication
public class SpringdocIntegrateApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringdocIntegrateApplication.class, args);
    }
}

我们定义了一个名为api_token的安全模式,并指定了其使用HTTP Bearer的方式。

  1. 使此安全模式生效
@Configuration
public class SpringDocConfig {
    @Bean
    public OpenAPI myOpenAPI() {
        return new OpenAPI()
                 ...
                .security(List.of(new SecurityRequirement().addList("api_token")));
    }
}

注意api_token正是我们第一步定义的那个Security schema。

经过上面两步后查看生成的API文档,你会发现其右上角出现了一个Authorize的按钮, 而且每个API的右边也出现了一把小锁,如下图所示。
在这里插入图片描述

当点击Authorize按钮后会弹出一个让你提供认证信息的弹出,其根据不同的认证方式会有所区别。

在这里插入图片描述
我们这里需要输入一个token,然后点击Authorize按钮后关闭此弹窗。你会发现每个API右边的那把小锁从打开状态变为了关闭状态,颜色也从灰色变成了黑色,证明其生效了。

然后我们再来请求一下API,就会正常返回了。

  1. 声明是否需要认证

默认情况下按照上面两步设置后,整个应用程序的API生效,但是有的API是不需要认证的,例如登录。
对于这种情况,我们可以使用@SecurityRequirements()来设置。

@RestController
@RequestMapping(value = "/admin",produces =  "application/json")
public class AuthController {
    ...
    @SecurityRequirements()
    @PostMapping("/login")
    public Result<String> login(@RequestBody LoginRequest request){
        return Result.ok("123");
    }
}

@SecurityRequirements() 里面需要一个String数组,里面列出需要使用的@SecurityScheme,例如我们这里的api_token。如果不写就说明不需要任何的安全模式,这里就是这种情况。

在这里插入图片描述
从上图可以看出,/admin/login这个API右边没有小锁的标志,表示其不需要认证。针对本案例来说,不需要认证的意思就是:在发起这个请求的时候,不在Authentication header里面附加token。

这里只是展示了HTTP bearer 这种安全模式,其他的原理类似,小朋友们可以开动你们聪明的大脑研究一下,给补充到这里。

总结

终于写完了,要写一篇逻辑清晰,对初学者友好的博客可真不容易。当然我写博客主要是为了自己梳理知识,但是我一直秉承着解决自己初次接触时候的困难场景来写的,相信对其他小朋友会有很大的帮助。

本文只是对Springdoc常用功能做了介绍,更个性化的功能还是要去看 Springdoc官网

最后,这么好的文章不给点个赞你还是那个无私奉献,互帮互助,开源博爱的IT人吗?

此情此景我想诵诗一首:

        端阳采撷
         
玉粽袭香千舸竞,艾叶黄酒可驱邪。
骑父稚子香囊佩,粉俏媳妇把景撷。

祝小朋友们端午节快乐!

源码

一如既往,你可以点击文章首发后,文末找到本文源码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/673794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

13. WebGPU 正交投影

在上一篇文章中&#xff0c;讨论了矩阵的工作原理。讨论了如何通过 1 个矩阵和一些神奇的矩阵数学来完成平移、旋转、缩放&#xff0c;甚至从像素到裁剪空间的投影。实现 3D 操作 只需要再向前迈一小步。 在之前的 2D 示例中&#xff0c;将 2D 点 (x, y) 乘以 3x3 矩阵。要实现…

【机器学习】——续上:卷积神经网络(CNN)与参数训练

目录 引入 一、CNN基本结构 1、卷积层 2、下采样层 3、全连接层 二、CNN参数训练 总结 引入 卷积神经网络&#xff08;CNN&#xff09;是一种有监督深度模型框架&#xff0c;尤其适合处理二维数据问题&#xff0c;如行人检测、人脸识别、信号处理等领域&#xff0c;是带…

19c rac添加节点

在正常的节点 [rootdb1 ~]# xhost access control disabled, clients can connect from any host [rootdb1 ~]# su - grid ASM1:/home/griddb1>export DISPLAY:1.0 ASM1:/home/griddb1>$ORACLE_HOME/gridSetup.sh [rootdb2 ~]# /tmp/GridSetupActions2021-09-16_…

基于Nginx1.22+PHP8+MySQL8安装Discuz! X3.5

基于Nginx1.22PHP8MySQL8安装Discuz! X3.5 1. 安装PHP82. 安装MySQL83. 配置Nginx1.224. 安装Discuz! X3.5 1. 安装PHP8 更新系统&#xff1a; yum update安装EPEL存储库&#xff1a; yum install epel-release安装Remi存储库&#xff08;提供了最新的 PHP 版本&#xff09;&…

【十三】druid 原理解析

druid 原理解析 先前写了一篇博客关于druid集成相关的&#xff0c;这里来分析一下druid原理&#xff0c;结合这两篇文章希望读者能够把druid理解透彻。 一、druid介绍 Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生&#xff0c;内置强大的监控功能&…

【前端JS交互篇】ECMA核心语法 ——常量、变量、数据类型、各种弹框

一、javascript简介 1.1 Javascript简史 在WEB日益发展的同时&#xff0c;网页的大小和复杂性不断增加&#xff0c;受制于网速的限制&#xff0c;为完成简单的表单验证而频繁地与服务器交换数据只会加重用户的负担&#xff0c;当时走在技术革新最前沿的Netscape&#xff08;网…

阿里云服务器的弹性计算能力如何?是否支持按需扩展和缩减?

阿里云服务器的弹性计算能力如何&#xff1f;是否支持按需扩展和缩减&#xff1f;   【本文由阿里云代理商[聚搜云www.4526.cn]撰写】   阿里云服务器&#xff0c;作为业界领先的云计算服务提供商&#xff0c;其弹性计算能力是如何体现的&#xff1f;是否真的支持按需扩展和…

定制你的Blocks UI布局:Gradio的Block Layouts模块介绍

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【python】如何在 Python 中创建相关矩阵

目录 一、说明 二、相关理论 2.1 何为相关 2.2 相关的前提 2.3 Correlation Matrix是个啥&#xff1f; 2.4 皮尔逊相关系数 三、Python演示如何创建相关矩阵 四、数据可视化观察 五、后记 一、说明 本教程介绍如何在 Python 中创建和解释相关矩阵。然而&#xff0c;创…

English Learning - L3 作业打卡 Lesson7 Day47 2023.6.20 周二

English Learning - L3 作业打卡 Lesson7 Day47 2023.6.20 周二 引言&#x1f349;句1: Growing up in a hot Las Vegas desert, all I wanted was to be free.成分划分弱读连读语调 &#x1f349;句2: I would daydream about traveling the world, living in a place where i…

有三个线程,分别只能打印A,B和C要求按顺序打印ABC,打印10次(多种方法,小白也懂)

目录 第一种方法:使用LockSupport的park和unpark功能(推荐) 第二种方式:synchronizedwaitnotify 第三种:暴力循环方法(不推荐) 第一种方法:使用LockSupport的park和unpark功能(推荐) 简单来说我们有一个名为LockSupport的方法 park就是阻塞当前进程 unpark就是取消阻塞让其…

DRIFTINGBLUES: 4实战演练

文章目录 DRIFTINGBLUES: 4实战演练一、前期准备1、相关信息 二、信息收集1、端口扫描2、访问网站3、查看源码4、解密5、访问网页6、解密7、访问网页8、微信扫一扫9、爆破FTP10、登录FTP11、下载文件并查看12、写入SSH密钥并上传13、SSH连接 三、后渗透1、查看第一个flag2、查找…

Golang | Web开发之Gin静态资源映射及HTML模板渲染

欢迎关注「全栈工程师修炼指南」公众号 点击 &#x1f447; 下方卡片 即可关注我哟! 设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习&#xff01; 专注 企业运维实践、网络安全、系统运维、应用开发、物联网实战、全栈文章 等知识分享 “ 花开堪折直须折&#xf…

[Eigen中文文档] 稀疏矩阵操作

文档总目录 本文目录 稀疏矩阵格式SparseMatrix 类 第一个示例SparseMatrix 类矩阵和向量属性迭代非零系数 填充稀疏矩阵支持的运算符和函数基本操作矩阵乘积块操作三角形视图和自共轭视图 英文原文(Sparse matrix manipulations) 处理和解决稀疏问题涉及各种模块&#xff0c…

【马蹄集】第十六周作业

第十六周作业 目录 MT2149 最长子段和MT2150 旅费MT2156 矩阵取数MT2157 迷宫MT2155 四柱河内塔 MT2149 最长子段和 难度&#xff1a;钻石    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目描述 给出一个长度为 n n n 的序列 A A A&#xff0c;选出其中连续…

Android studio的安装的详细过程

Android开发环境 Eclipse Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环境&#xff0c;2001年11月贡献给开源社区&#xff0c;现在它由非营利软件供应商联盟Eclipse基金会&#xff08;Eclipse Foundation&#xff09;管理。 Eclipse是一种面…

动手实现条件随机场(上)

引言 本文基于PyTorch实现条件随机场&#xff0c;实现CRF层参考论文Neural Architectures for Named Entity Recognition中关于CRF层的描述。包含大量的图解和例子说明&#xff0c;看完一定能理解&#xff01; 论文地址&#xff1a; https://arxiv.org/pdf/1603.01360.pdf 也可…

【Linux】随机数的生成

生成随机数目录 生成随机数&#xff1a;默认为(0-32767)生成指定区间随机数&#xff1a;随机生成1-50之间的数随机生成时间戳秒和纳秒加密运算生成一个随机字符指定10个在使用md5sum校验/dev/random是什么&#xff1f; 生成随机的UUID加密算法相关文章 生成随机数&#xff1a;默…

CODESYS斜坡函数功能块(ST源代码)

SMART PLC梯形图斜坡函数FC请参看下面文章链接: SMART PLC斜坡函数功能块(梯形图代码)_RXXW_Dor的博客-CSDN博客斜坡函数Ramp的具体应用可以参看下面的文章链接:PID优化系列之给定值斜坡函数(PLC代码+Simulink仿真测试)_RXXW_Dor的博客-CSDN博客很多变频器里的工艺PID,…

Gradio Blocks:queue、integrate和load方法介绍

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…