重学Spring系列之Swagger2.0和Swagger3.0

大忽悠爱忽悠 2021-11-25 18:25:53
spring swagger 系列 重学 swagger2.0


使用Swagger2构建API文档

为什么要发布API接口文档

当下很多公司都采取前后端分离的开发模式,前端和后端的工作由不同的工程师完成。在这种开发模式下,维护一份及时更新且完整的API 文档将会极大的提高我们的工作效率。传统意义上的文档都是后端开发人员使用word编写的,相信大家也都知道这种方式很难保证文档的及时性,这种文档久而久之也就会失去其参考意义,反而还会加大我们的沟通成本。而 Swagger 给我们提供了一个全新的维护 API 文档的方式,下面我们就来了解一下它的优点

  • 代码变,文档变。只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性。
  • 跨语言性,支持 40 多种语言。
  • Swagger UI 呈现出来的是一份可交互式的 API 文档,我们可以直接在文档页面尝试 API的调用,省去了准备复杂的调用参数的过程。
  • 还可以将文档规范导入相关的工具(例如 SoapUI), 这些工具将会为我们自动地创建自动化测试。

整合swagger2生成文档

首先通过maven坐标引入swagger相关的类库。

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>

然后通过java Config对Swagger2进行配置。

@Configuration
@EnableSwagger2
public class Swagger2 {

private ApiInfo apiInfo() {

return new ApiInfoBuilder()
.title("springboot利用swagger构建api文档")
.description("简单优雅的restfun风格")
.termsOfServiceUrl("https://blog.csdn.net/m0_53157173")
.version("1.0")
.build();
}
@Bean
public Docket createRestApi() {

return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//扫描basePackage包下面的“/rest/”路径下的内容作为接口文档构建的目标
.apis(RequestHandlerSelectors.basePackage("com.controller"))
.paths(PathSelectors.regex("/rest/.*"))
.build();
}
}
  • @EnableSwagger2 注解表示开启SwaggerAPI文档相关的功能
  • 在apiInfo方法中配置接口文档的title(标题)、描述、termsOfServiceUrl(服务协议)、版本等相关信息
  • 在createRestApi方法中,basePackage表示扫描哪个package下面的Controller类作为API接口文档内容范围
  • 在createRestApi方法中,paths表示哪一个请求路径下控制器映射方法,作为API接口文档内容范围

集成完成之后,做一下访问验证:http://localhost/swagger-ui.html ,如下:

在这里插入图片描述
swagger不仅提供了静态的接口文档的展示,还提供了执行接口方法测试的功能。在下图中填入接口对应的参数,点击“try it out"就可以实现接口请求的发送与响应结果的展示。

在这里插入图片描述


书写swagger注解

通常情况下Controller类及方法书写了swagger注解,就不需要写java注释了。但是笔者从来几乎都不写swagger注解,也就是说本小节(三、书写swagger注解)所讲的内容笔者从来都不用。因为一个成熟的团队,前端人员根据英文方法的名称和参数名称就能知道方法的作用,前提是代码开发者认真的为接口及参数起英文名。通过团队内推广RESTful接口的设计原则和良好的统一的交互规范,就能知道响应结果的含义。这也是一种“约定大于配置”的体现。

当然,如果你的团队没有“约定“,那么就需要“配置”来做文档说明。我通常把这个过程叫做“为接口功能添加注释”。写法如下:

@ApiOperation(value = "添加文章", notes = "添加新的文章", tags = "Article",httpMethod = "POST")
@ApiImplicitParams({

@ApiImplicitParam(name = "title", value = "文章标题", required = true, dataType = "String"),
@ApiImplicitParam(name = "content", value = "文章内容", required = true, dataType = "String"),
@ApiImplicitParam(name = "author", value = "文章作者", required = true, dataType = "String")
})
@ApiResponses({

@ApiResponse(code=200,message="成功",response=AjaxResponse.class),
})
@PostMapping("/article")
public @ResponseBody AjaxResponse saveArticle(
@RequestParam(value="title") String title, //参数1
@RequestParam(value="content") String content,//参数2
@RequestParam(value="author") String author,//参数3
) {

swagger注释添加完成之后,接口文档变成如下的样子(含有中文说明):

在这里插入图片描述
ApiModel注解的用法

@ApiModel(value = "通用响应数据结构类")
public class AjaxResponse {

@ApiModelProperty(value="请求是否处理成功")
private boolean isok; //请求是否处理成功
@ApiModelProperty(value="请求响应状态码",example="200、400、500")
private int code; //请求响应状态码(200、400、500)
@ApiModelProperty(value="请求结果描述信息")
private String message; //请求结果描述信息
@ApiModelProperty(value="请求结果数据")
private Object data; //请求结果数据(通常用于查询操作)
}

页面显示结果

在这里插入图片描述


虽然笔者自己从来都不写swagger注解,但不排除有的团队觉得可以用,所以还是详细介绍一下:

@Api:用在Controller控制器类上
属性tags="说明该类的功能及作用"
@ApiOperation:用在Controller控制器类的请求的方法上
value="说明方法的用途、作用"
notes="方法的备注说明"
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:请求方法中参数的说明
name:参数名
value:参数的汉字说明、解释、用途
required:参数是否必须传,布尔类型
paramType:参数的类型,即参数存储位置或提交方式
· header --> HttpHeader携带的参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam (如上面的例子)
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· body(不常用)
· form(不常用)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
@ApiResponses:用在控制器的请求的方法上,对方法的响应结果进行描述
@ApiResponse:用于表达一个响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:响应结果封装类,如上例子中的AjaxResponse.class
@ApiModel:value=“通常用在描述@RequestBody@ResponseBody注解修饰的接收参数或响应参数实体类”
@ApiModelProperty:value="实体类属性的描述"

生产环境下如何禁用swagger2

我们的文档通常是在团队内部观看及使用的,不希望发布到生产环境让用户看到。

  • 禁用方法1:使用注解@Profile({“dev”,“test”})表示在开发或测试环境开启,而在生产关闭。
  • 禁用方法2:使用注解@ConditionalOnProperty(name = “swagger.enable”,havingValue = “true”) 然后在测试配置或者开发配置中 添加 swagger.enable = true即可开启,生产环境不填则默认关闭Swagger.

使用Swagger2Markup实现导出API文档

Swagger2Markup是Github上的一个开源项目。该项目主要用来将Swagger自动生成的文档转换成几种流行的格式以便于静态部署和使用,比如:AsciiDoc、Markdown、Confluence。

在这里插入图片描述

生成AsciiDoc

生成AsciiDoc的方式有两种:

通过Java代码来生成

第一步:编辑pom.xml增加需要使用的相关依赖和仓库

<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup</artifactId>
<version>1.3.3</version>
</dependency>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
<id>jcenter-releases</id>
<name>jcenter</name>
<url>http://jcenter.bintray.com</url>
</repository>
</repositories>

第二步:编写一个单元测试用例来生成执行生成文档的代码

/** * 生成AsciiDocs格式文档 * @throws Exception */
@Test
public void generateAsciiDocs() throws Exception {

// 输出Ascii格式
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://127.0.0.1:8082/v2/api-docs"))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/asciidoc/generated"));
}
/** * 生成Markdown格式文档 * @throws Exception */
@Test
public void generateMarkdownDocs() throws Exception {

// 输出Markdown格式
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8082/v2/api-docs"))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/markdown/generated"));
}
/** * 生成Confluence格式文档 * @throws Exception */
@Test
public void generateConfluenceDocs() throws Exception {

// 输出Confluence使用的格式
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8082/v2/api-docs"))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/confluence/generated"));
}
/** * 生成AsciiDocs格式文档,并汇总成一个文件 * @throws Exception */
@Test
public void generateAsciiDocsToFile() throws Exception {

// 输出Ascii到单文件
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8082/v2/api-docs"))
.withConfig(config)
.build()
.toFile(Paths.get("./docs/asciidoc/generated/all"));
}
/** * 生成Markdown格式文档,并汇总成一个文件 * @throws Exception */
@Test
public void generateMarkdownDocsToFile() throws Exception {

// 输出Markdown到单文件
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8082/v2/api-docs"))
.withConfig(config)
.build()
.toFile(Paths.get("./docs/markdown/generated/all"));
}

以上代码内容很简单,大致说明几个关键内容:

  • MarkupLanguage.ASCIIDOC:指定了要输出的最终格式。除了ASCIIDOC之外,还有MARKDOWN和CONFLUENCE_MARKUP
  • from(new URL("http://localhost:8080/v2/api-docs"):指定了生成静态部署文档的源头配置,可以是这样的URL形式,也可以是符合Swagger规范的String类型或者从文件中读取的流。如果是对当前使用的Swagger项目,我们通过使用访问本地Swagger接口的方式,如果是从外部获取的Swagger文档配置文件,就可以通过字符串或读文件的方式
  • toFolder(Paths.get("src/docs/asciidoc/generated"):指定最终生成文件的具体目录位置

如果不想分割结果文件,也可以通过替换toFolder(Paths.get("src/docs/asciidoc/generated")toFile(Paths.get("src/docs/asciidoc/generated/all")),将转换结果输出到一个单一的文件中,这样可以最终生成html的也是单一的。

在执行了上面的测试用例之后,我们就能在当前项目的目录下获得如下内容:

在这里插入图片描述

可以看到,这种方式在运行之后就生成出了5个不同的静态文件。


通过Maven插件来生成

除了通过上面编写Java代码来生成的方式之外,swagger2markup还提供了对应的Maven插件来使用。对于上面的生成方式,完全可以通过在pom.xml中增加如下插件来完成静态内容的生成。

<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.6</version>
<configuration>
<sourceDirectory>./docs/asciidoc/generated</sourceDirectory>
<outputDirectory>./docs/asciidoc/html</outputDirectory>
<headerFooter>true</headerFooter>
<doctype>book</doctype>
<backend>html</backend>
<sourceHighlighter>coderay</sourceHighlighter>
<attributes>
<!--菜单栏在左边-->
<toc>left</toc>
<!--多标题排列-->
<toclevels>3</toclevels>
<!--自动打数字序号-->
<sectnums>true</sectnums>
</attributes>
</configuration>
</plugin>

在这里插入图片描述
配置执行命令

通过上面的配置,执行该插件的asciidoctor:process-asciidoc命令之后,就能在docs/asciidoc/html目录下生成最终可用的静态部署HTML了。在完成生成之后,可以直接通过浏览器来看查看,你就能看到类似下图的静态部署结果:

在这里插入图片描述


可以参考的文章

使用Swagger2Markup实现导出API文档

Swagger文档转Word 文档

github

spring boot2.0+swagger自动生成PDF和HTML格式的API文档

swagger+asciidoctor 导出PDF中文缺失乱码问题解决


Swagger3-即OpenAPI使

OpenAPI是规范的正式名称。规范的开发工作于2015年启动,当时SmartBear(负责Swagger工具开发的公司)将Swagger 2.0规范捐赠给了Open API Initiative,该协会由来自技术领域不同领域的30多个组织组成。此后,该规范被重命名为OpenAPI规范。

Swagger

  • 是一个 API文档维护组织,后来成为了 Open API 标准的主要定义者。现在最新的版本为17年发布的 Swagger3(Open Api3)。
  • 是一个Open API规范实现工具包,由于Swagger工具是由参与创建原始Swagger规范的团队开发的,因此通常仍将这些工具视为该规范的代名词。目前可以认为Swagger3就是Open API 3.0

OpenAPI 3.0:2017年7月,Open API Initiative最终发布了OpenAPI Specification 3.0.0。它对2.0规范进行了很多改进。Open API 3.0规范可以用JSON或YAML编写,并且在记录RESTful API方面做得很好。同时标志着Swagger2成为过去式。

SpringFox是 spring 社区维护的一个项目(非官方),帮助使用者将 swagger2 集成到 Spring 中。常常用于 Spring 中帮助开发者生成文档,并可以轻松的在spring boot中使用。截至2020年4月,尚未支持 OpenAPI3 标准。

SpringDoc也是 spring 社区维护的一个项目(非官方),帮助使用者将 swagger3 集成到 Spring 中。
也是用来在 Spring 中帮助开发者生成文档,并可以轻松的在spring boot中使用


整合springdoc-openapi

在pom.xml里面去掉springfox,添加如下的openapi依赖。

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

就这么简单,文档就构建完成了,不需要做任何的其他配置。

访问:http://localhost:8888/swagger-ui.html

在这里插入图片描述


将API分组分组展示

配置方法

@Configuration
public class OpenAPIConfig {

@Bean
public GroupedOpenApi restApi() {

return GroupedOpenApi.builder()
.group("rest-api")
.pathsToMatch("/rest/**")
.build();
}
@Bean
public GroupedOpenApi helloApi() {

return GroupedOpenApi.builder()
.group("hello")
.pathsToMatch("/hello/**")
.build();
}
}

显示效果,通过下拉选择分组,查看组内API
在这里插入图片描述


使用 swagger3 注解代替 swagger2注解

如果你希望为文档加上更详细的中文注释,使用如下注解(对比Swagger2注解使用方法使用即可)。但是笔者觉得没有必要学习这东西,意义不大。注意变量、接口命名规范,英文的接口文档就挺好。

用 swagger 3 的注解(已经在上面maven包引入)代替 swagger 2 的注解,swagger 3 注解的包路径为io.swagger.v3.oas.annotations。

在这里插入图片描述


swagger3.0 第三方版本参考:

swagger3

版权声明
本文为[大忽悠爱忽悠]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_53157173/article/details/121524836

  1. Java经典面试题详解,突围金九银十面试季(附详细答案,mysql集群架构部署方案
  2. java整理,java高级特性编程及实战第一章
  3. java教程——反射,mongodb下载教程
  4. Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day12,zookeeper原理作用
  5. Java后端互联网500道中高级面试题(含答案),linux钩子技术
  6. java8 Stream API及常用方法,java初级程序员面试
  7. java-集合-Map(双列)——迪迦重制版,2021Java开发社招面试解答之性能优化
  8. Flink处理函数实战之二:ProcessFunction类,java线程面试题目
  9. flex 布局详解,【Java面试题
  10. Linux basic command learning
  11. Why did docker lose to kubernetes? Docker employee readme!
  12. MySQL安装
  13. Elastic Search Aggregate Learning five: Problem Analysis of Uncertainty of sequencing results, Alibaba Java Performance Tuning Practical
  14. Installing, configuring, starting and accessing rabbitmq under Linux
  15. Oracle SQL injection summary
  16. Installation MySQL
  17. L'exposition à la photo d'essai sur la route i7 du nouveau vaisseau amiral de BMW Pure Electric a également été comparée à celle de Xiaopeng p7.
  18. spring JTA 关于异常处理的时机问题
  19. Le problème du temps de traitement des exceptions dans la JTA printanière
  20. Flink Handling Function Real War II: processfunction class, Java thread interview subject
  21. Oracle SQL injection summary
  22. [Java data structure] you must master the classic example of linked list interview (with super detailed illustration and code)
  23. Do you really know MySQL order by
  24. Record a java reference passing problem
  25. spring JTA 關於异常處理的時機問題
  26. Java - Set - Map (double file) - dija Rewriting, 2021 Java Developer's Performance Optimization
  27. Android入门教程 | OkHttp + Retrofit 取消请求的方法
  28. Java 8 Stream API and common methods, Java Junior Program interview
  29. Github 疯传!史上最强!BAT 大佬,2021年最新Java大厂面试笔试题分享
  30. git(3)Git 分支,zookeeper下载教程
  31. Java Backend Internet 500 questions d'entrevue moyennes et avancées (y compris les réponses), technologie de crochet Linux
  32. Entretien d'entretien d'usine Java post sprint de 100 jours - accumulation de jours et de mois, trois questions par jour [jour 12, fonction de principe de Zookeeper
  33. Tutoriel Java - reflection, tutoriel de téléchargement mongodb
  34. How to analyze several common key and hot issues in redis from multiple dimensions
  35. GIT (3) GIT Branch, Zookeeper Download tutoriel
  36. Tutoriel de démarrage Android | okhttp + Retrofit comment annuler une demande
  37. Design pattern [3.3] - Interpretation of cglib dynamic agent source code
  38. Share the actual operation of private collection project nodejs backend + Vue + Mysql to build a management system
  39. Springboot has 44 application initiators
  40. GitHub上霸榜久居不下的《Java面试突击宝典》,java图形用户界面设计基础
  41. GitHub上访问下载破百万的神仙文档《Java面试神技》看完我呆了,java面试问项目中遇到的问题
  42. GitHub上标星75k 超牛的《Java面试突击版,java高级工程师技能
  43. GitHub上标星2,java项目开发实训教程
  44. Docker development environment Preview
  45. JavaScript高級深入淺出:掌握 this 指向
  46. JavaScript Advanced Insight and outside: Mastering this direction
  47. Vue de l'application pratique de Javascript, drop drag Event
  48. docker 安装部署 Jenkins 2.322
  49. kafka安装
  50. 近九万字图文详解RabbitMQ
  51. Engaged in Java for one and a half years, how to break through yourself
  52. 输出9*9乘法表----java
  53. 判断一个数是不是素数-------java
  54. java项目,记录页面修改值,内部打“官司”用
  55. Docker installation Deployment Jenkins 2.322
  56. Comment porter un pantalon en hiver? Les petits hommes, les jambes épaisses et la largeur de l'entrejambe peuvent être vus. 3 techniques pour éviter la foudre
  57. MySQL下载和安装教程
  58. In depth analysis of rocketmq source code - message storage module
  59. Spring transaction management
  60. mysql恢复ibd数据,为何频频报错?