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

news/2024/11/24 21:04:40/

[版权申明] 非商业目的注明出处可自由转载
出自: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 {@Beanpublic 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 {...@Beanpublic GroupedOpenApi publicApi() {return GroupedOpenApi.builder().group("api").pathsToMatch("/api/**").build();}@Beanpublic 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 {...@Overrideprotected 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 {@Beanpublic 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.ppmy.cn/news/515344.html

相关文章

MySQL——存储过程与存储函数

MySQL从5.0版本开始支持存储过程和存储函数。存储过程和函数能够将复杂的SQL逻辑封装在一起&#xff0c;应用程序无须关注存储过程和函数内部复杂的SQL逻辑&#xff0c;而只需要简单地调用存储过程和函数即可。 1. 存储过程概述 1.1 理解 含义&#xff1a;存储过程的英文是 S…

芯力特CAN接口芯片,SIT1050T参数及描述

完全兼容“ISO 11898”标准&#xff1b; 内置过温保护&#xff1b; 过流保护功能&#xff1b; 显性超时功能&#xff1b; 静音模式&#xff1a;未上电节点不干扰总线&#xff1b; 至少允许 110 个节点连接到总线&#xff1b; 高速 CAN&#xff0c;传输速率可达到 1Mbps&#xf…

上海航芯 |带CAN的128k Flash通用MCU ACM32F0优势

• 车规级工艺(-40到125度), 消费级价格&#xff0c;适用于户外或者高温宽范围的严苛场景 • 带CAN的128k flash F0&#xff0c;适用于需要CAN的车载或者工业场景 • 断码LCD触控超低功耗&#xff0c;适用于低功耗物联网场景 • 2个QSPI&#xff0c;8根SPI数据线&#xff0c;适…

C8051F500 C8051F50X CAN总线收发数据 中文寄存器

** C8051F500 C8051F50X CAN总线收发数据中文寄存器 ** 一、最近手头有一个汽车项目用到CAN总线进行通信&#xff0c;使用的芯片是C8051F500&#xff1b;这个芯片具有CAN 2.0协议&#xff1b;它和早期的C8051F04X和06x的使用和寄存器的定义有些不同&#xff1b; C8051F50X的寄…

HC32L110国产超低功耗华大MCU芯片介绍

华大HC32L110 系列32 位 ARM Cortex-M0 微控制器 HC32L110 系列是一款旨在延长便携式测量系统的电池使用寿命的超低功耗、Low Pin Count、宽电压工作范围的 MCU。集成 12 位 1M sps 高精度 SARADC 以及集成了比较器、多路 UART、SPI、I 2 C等丰富的通讯外设&#xff0c;具有高…

ASEMI代理NXP汽车芯片MKE02Z32VLC4

编辑-Z NXP汽车芯片MKE02Z32VLC4参数&#xff1a; 型号&#xff1a;MKE02Z32VLC4 资格状态&#xff1a;M完全合格的一般市场流量&#xff0c;P资格预审 动脉炎家族&#xff1a;KE02型 关键点属性&#xff1a;Z M0 core 程序闪存大小&#xff1a;16 16 KB&#xff0c;32…

HC32L136国产超低功耗华大MCU芯片介绍

华大HC32L136 系列32 位 ARM Cortex-M0 微控制器 HC32L136 系列是一款旨在延长便携式测量系统的电池使用寿命的超低功耗、宽电压工作范围的 MCU。集成 12 位 1M sps 高精度 SARADC&#xff0c;以及集成了比较器、运放、内置高性能 PWM 定时器、LCD 显示、多路 UART、SPI、I2C …

KT404A芯片使用手册_4.参考电路

4.参考电路 争对芯片的应用&#xff0c;我们提供了详细的设计参考&#xff0c;让您可以更快的上手体验到该芯片的强大功能 串行通信接口&#xff0c;波特率默认9600&#xff0c;可以根据客户的要求修改外部的IO按键的功能可以按照客户需求订制外部单声道功放参考电路 4.1串行…