前言

相信很多后端开发在项目中都会碰到要写 api 文档,不管是给前端、移动端等提供更好的对接,还是以后为了以后交接方便,都会要求写 api 文档。

而手写 api 文档的话有诸多痛点:

  • 文档更新的时候,需要再次发送给对接人
  • 接口太对,手写文档很难管理
  • 接口返回的结果不明确
  • 不能直接在线测试接口,通常需要使用工具,如 postman 等

Swagger 就很好的解决了这个问题。

Swagger 简介

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

官网:https://swagger.io

Swagger 使用

1.相关依赖

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

2.Swagger 配置类

@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket buildDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(buildApiInf()) //将api的元信息设置为包含在json resourcelisting响应中
//.host("127.0.0.1:8080") //设置ip和端口,或者域名
.select() //启动用于api选择的生成器
//.apis(RequestHandlerSelectors.any())
.apis(RequestHandlerSelectors.basePackage("cn.zwqh.springboot.controller"))//指定controller路径
.paths(PathSelectors.any()).build();
} private ApiInfo buildApiInf() { Contact contact=new Contact("朝雾轻寒","https://www.zwqh.top/","zwqh@clover1314.com");
return new ApiInfoBuilder()
.title("Swagger Demo Restful API Docs")//文档标题
.description("Swagger 示例 Restful Api 文档")//文档描述
.contact(contact)//联系人
.version("1.0")//版本号
//.license("")//更新此API的许可证信息
//.licenseUrl("")//更新此API的许可证Url
//.termsOfServiceUrl("")//更新服务条款URL
.build(); }
}

3.Spring MVC 相关配置

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 静态资源配置(默认)
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");// 静态资源路径
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
} }

如果不添加此静态资源配置会报错,找不到相关路径

4.Model 中使用 Swagger 注解

@ApiModel(value = "UserEntity", description = "用户对象")
public class UserEntity implements Serializable{ /**
*
*/
private static final long serialVersionUID = 5237730257103305078L;
@ApiModelProperty(value ="用户id",name="id",dataType="Long",required = false,example = "1",hidden = false )
private Long id;
@ApiModelProperty(value ="用户名",name="userName",dataType="String",required = false,example = "关羽" )
private String userName;
@ApiModelProperty(value ="用户性别",name="userSex",dataType="String",required = false,example = "男" )
private String userSex; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getUserSex() {
return userSex;
} public void setUserSex(String userSex) {
this.userSex = userSex;
} }

5. Controller 中使用 Swagger 注解


@RestController
@RequestMapping("/api")
@Api(tags = { "接口分组1", "接口分组2" })
public class ApiController { @Autowired
private UserDao userDao; @GetMapping("/getAllUser")
@ApiOperation(value = "获取所有用户", notes = "", httpMethod = "GET", tags = "接口分组3")
public List<UserEntity> getAll() {
return userDao.getAll();
} @GetMapping("/getUserById")
@ApiOperation(value = "根据id获取用户", notes = "id必传", httpMethod = "GET")
@ApiImplicitParam(name = "id", value = "用户id",example = "1", required = true, dataType = "long", paramType = "query")
public UserEntity getOne(Long id) {
return userDao.getOne(id);
} @PostMapping("/getUserByNameAndSex")
@ApiOperation(value = "根据name和sex获取用户", notes = "", httpMethod = "POST")
@ApiImplicitParams({
@ApiImplicitParam(name = "userName", value = "用户名", example = "关羽", required = true, dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "userSex", value = "用户性别", example = "男", required = true, dataType = "string", paramType = "query") })
public UserEntity getUserByNameAndSex(String userName, String userSex) {
return userDao.getUserByNameAndSex(userName, userSex);
} @PostMapping("/insertUser")
@ApiOperation(value = "新增用户", notes = "传json,数据放body", httpMethod = "POST")
@ApiImplicitParams({
@ApiImplicitParam(name = "body", value = "用户对象json", example = "{userName:'朝雾轻寒',userSex:'男'}", required = true) })
public String insertUser(@RequestBody String body) {
System.out.println(body);
UserEntity user = JSON.parseObject(body, UserEntity.class);
userDao.insertUser(user);
return "{code:0,msg:'success'}";
} @PostMapping("/updateUser")
@ApiOperation(value = "修改用户", notes = "传json,数据放body", httpMethod = "POST")
@ApiImplicitParams({
@ApiImplicitParam(name = "body", value = "用户对象json", example = "{id:23,userName:'朝雾轻寒',userSex:'女'}", required = true) })
public String updateUser(@RequestBody String body) {
System.out.println(body);
UserEntity user = JSON.parseObject(body, UserEntity.class);
userDao.updateUser(user);
return "{code:0,msg:'success'}";
} @PostMapping("/deleteUser")
@ApiOperation(value = "删除用户", notes = "id必传", httpMethod = "POST")
public String deleteUser(@ApiParam(name = "id", value = "用户id", required = true) Long id) {
userDao.deleteUser(id);
return "{code:0,msg:'success'}";
}
}

5.测试

访问 http://127.0.0.1:8080/swagger-ui.html 进行接口在线测试

Swagger 常用注解

1.@Api

用于类,表示标识这个类是swagger的资源。属性如下:

  • tags 表示说明,tags如果有多个值,会生成多个列表
  • value 表示说明,可以使用tags替代

2.@ApiOperation

用于方法,表示一个http请求的操作。属性如下:

  • value 用于方法描述
  • notes 用于提示内容
  • tags 用于API文档控制的标记列表,视情况而用,可以进行独立分组

3.@ApiParam

用于方法、参数、字段说明;表示对参数的添加元数据。

  • name 参数名
  • value 参数说明
  • required 是否必填

4.@ApiModel

用于类,表示对类进行说明,用于参数用实体类接受。

  • value 对象名
  • description 描述

5.@ApiModelProperty

用于方法、字段,表示对model属性的说明或者数据操作更改。

  • value 字段说明
  • name 重写属性名
  • dataType 重写属性数据类型
  • required 是否必填
  • example 举例说明
  • hidden 隐藏

6.@ApiIgnore

用于类、方法、方法参数,表示这个方法或者类被忽略,不在swagger-ui.html上显示。

7.@ApiImplicitParam

用于方法,表示单独的请求参数。

  • name 参数名
  • value 参数说明
  • dataType 数据类型
  • paramType 参数类型
  • example 举例说明

8.@ApiImplicitParams

用于方法,包含多个 @ApiImplicitParam。

9.@ApiResponses @ApiResponse

用于类或者方法,描述操作的可能响应。

  • code 响应的HTTP状态代码
  • message 响应附带的可读消息

10.@ResponseHeader

用于方法,响应头设置。

  • name 响应头名称
  • description 头描述
  • response 默认响应类 void
  • responseContainer 参考ApiOperation中配置

Swagger 导出离线 api 文档

1.导出 AsciiDocs、Markdown、Confluence 格式文档

添加依赖

<!-- swagger2markup 相关依赖 -->
<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup</artifactId>
<version>1.3.3</version>
</dependency>

转换工具类

public class SwaggerUtils {

	private static final String url = "http://127.0.0.1:8080/v2/api-docs";
/**
* 生成AsciiDocs格式文档
* @throws MalformedURLException
*/
public static void generateAsciiDocs() throws MalformedURLException {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema().build(); Swagger2MarkupConverter.from(new URL(url))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/asciidoc/generated"));
}
/**
* 生成AsciiDocs格式文档,并汇总成一个文件
* @throws MalformedURLException
*/
public static void generateAsciiDocsToFile() throws MalformedURLException {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build(); Swagger2MarkupConverter.from(new URL(url))
.withConfig(config)
.build()
.toFile(Paths.get("./docs/asciidoc/generated/all"));
} /**
* 生成Markdown格式文档
* @throws MalformedURLException
*/
public static void generateMarkdownDocs() throws MalformedURLException {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build(); Swagger2MarkupConverter.from(new URL(url))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/markdown/generated"));
}
/**
* 生成Markdown格式文档,并汇总成一个文件
* @throws MalformedURLException
*/
public static void generateMarkdownDocsToFile() throws MalformedURLException {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build(); Swagger2MarkupConverter.from(new URL(url))
.withConfig(config)
.build()
.toFile(Paths.get("./docs/markdown/generated/all"));
} /**
* 生成Confluence格式文档
* @throws MalformedURLException
*/
public static void generateConfluenceDocs() throws MalformedURLException {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build(); Swagger2MarkupConverter.from(new URL(url))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/confluence/generated"));
} /**
* 生成Confluence格式文档,并汇总成一个文件
* @throws MalformedURLException
*/
public static void generateConfluenceDocsToFile() throws MalformedURLException {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build(); Swagger2MarkupConverter.from(new URL(url))
.withConfig(config)
.build()
.toFile(Paths.get("./docs/confluence/generated/all"));
} }

使用测试 Controller

@RestController
@RequestMapping("/export")
@ApiIgnore
public class ExportController { @RequestMapping("/ascii")
public String exportAscii() throws MalformedURLException{
SwaggerUtils.generateAsciiDocs();
return "success";
} @RequestMapping("/asciiToFile")
public String asciiToFile() throws MalformedURLException{
SwaggerUtils.generateAsciiDocsToFile();
return "success";
} @RequestMapping("/markdown")
public String exportMarkdown() throws MalformedURLException{
SwaggerUtils.generateMarkdownDocs();
return "success";
} @RequestMapping("/markdownToFile")
public String exportMarkdownToFile() throws MalformedURLException{
SwaggerUtils.generateMarkdownDocsToFile();
return "success";
} @RequestMapping("/confluence")
public String confluence() throws MalformedURLException{
SwaggerUtils.generateConfluenceDocs();
return "success";
} @RequestMapping("/confluenceToFile")
public String confluenceToFile() throws MalformedURLException{
SwaggerUtils.generateConfluenceDocsToFile();
return "success";
}
}

2.导出 html、pdf、xml 格式

添加依赖

<!--离线文档 -->
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<!--springfox-staticdocs 生成静态文档 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-staticdocs</artifactId>
<version>2.6.1</version>
</dependency>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<swaggerInput>http://127.0.0.1:8080/v2/api-docs</swaggerInput>
<outputDir>./docs/asciidoc/generated</outputDir>
<config>
<swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
</config>
</configuration>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.3</version>
<!-- <version>2.0.0-RC.1</version> -->
<!-- Include Asciidoctor PDF for pdf generation -->
<dependencies>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj-pdf</artifactId>
<version>1.5.0-alpha.10.1</version>
</dependency>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
<configuration>
<sourceDirectory>./docs/asciidoc/generated</sourceDirectory>
<outputDirectory>./docs/asciidoc/html</outputDirectory>
<backend>html</backend>
<!-- <outputDirectory>./docs/asciidoc/pdf</outputDirectory>
<backend>pdf</backend> -->
<headerFooter>true</headerFooter>
<doctype>book</doctype>
<sourceHighlighter>coderay</sourceHighlighter>
<attributes>
<!-- 菜单栏在左边 -->
<toc>left</toc>
<!-- 多标题排列 -->
<toclevels>3</toclevels>
<!-- 自动打数字序号 -->
<sectnums>true</sectnums>
</attributes>
</configuration>
</plugin>
</plugins>
</pluginManagement> </build>

可以修改此处 html 和 pdf,通过 mvn asciidoctor:process-asciidoc 可以导出相应格式文件

<outputDirectory>./docs/asciidoc/html</outputDirectory>
<backend>html</backend>

执行 mvn asciidoctor:process-asciidoc 后再执行 mvn generate-resources,可在 targt/generated-docs 目录下生成 xml 格式文件。

完整代码

github

码云

Spring Boot 2.X(十五):集成 Swagger2 开发 API 文档(在线+离线)的更多相关文章

  1. ant design pro (十五)advanced 使用 API 文档工具

    一.概述 原文地址:https://pro.ant.design/docs/api-doc-cn 在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难 ...

  2. Spring Boot中使用Swagger2构建API文档

    程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...

  3. 使用springfox+swagger2书写API文档(十八)

    使用springfox+swagger2书写API文档 springfox是通过注解的形式自动生成API文档,利用它,可以很方便的书写restful API,swagger主要用于展示springfo ...

  4. 白话SpringCloud | 第十一章:路由网关(Zuul):利用swagger2聚合API文档

    前言 通过之前的两篇文章,可以简单的搭建一个路由网关了.而我们知道,现在都奉行前后端分离开发,前后端开发的沟通成本就增加了,所以一般上我们都是通过swagger进行api文档生成的.现在由于使用了统一 ...

  5. SpringBoot+rest接口+swagger2生成API文档+validator+mybatis+aop+国际化

    代码地址:JillWen_SpringBootDemo mybatis 1. 添加依赖: <dependency> <groupId>org.mybatis.spring.bo ...

  6. spring boot 2.x 系列——spring-boot 集成 Swagger2 打造在线接口文档

    文章目录 一.Springfox 与 Swagger 简介 1.1 Springfox 1.2 Swagger 1.3 OpenApi.Swagger.Springfox的关系 二.spring bo ...

  7. 学习Spring Boot:(六) 集成Swagger2

    前言 Swagger是用来描述和文档化RESTful API的一个项目.Swagger Spec是一套规范,定义了该如何去描述一个RESTful API.类似的项目还有RAML.API Bluepri ...

  8. Spring Boot 整合Swagger2构建API文档

    1.pom.xml中引入依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>spri ...

  9. Spring Boot 系列(七)Swagger2-生成RESTful接口文档

    Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服 ...

随机推荐

  1. Spring Cloud Gateway 使用

    简介 Spring Cloud Gateway是Spring Cloud官方推出的网关框架,网关作为流量入口,在微服务系统中有着十分重要的作用,常用功能包括:鉴权.路由转发.熔断.限流等. Sprin ...

  2. Angular 路由守卫

    1. 路由 Angular路由: 可以控制页面跳转:可以在多视图间切换: 2. 路由守卫 Angular路由守卫: 在进入或离开某路由时,用于判断是否可以离开.进入某路由::: return true ...

  3. 1. jQuery中的DOM操作

    1)查找节点 通过jQuery选择器来完成 2)创建节点 创建元素节点:var newTd = $("<td></td>") 创建文本节点:在创建元素节点时 ...

  4. Java 2019 生态圈使用报告,这结果你赞同吗?

    这是国外一机构调查了 7000 名开发者得出来的 Java 2019 年生态圈工具使用报告,主要调查了 Java 版本.开发框架.web 服务器等使用情况.虽然只有 7000 名开发者参与调查,这数目 ...

  5. 02-28 scikit-learn库之线朴素贝叶斯

    目录 scikit-learn库之朴素贝叶斯 一.MultinomialNB 1.1 使用场景 1.2 代码 1.3 参数详解 1.4 属性 1.5 方法 二.GaussianNB 三.Bernoul ...

  6. DRF框架学习总结

    DRF框架安装配置及其功能概述 Django与DRF 源码视图解析 DRF框架序列化和返序列化 DRF框架serializers中ModelSerializer类简化序列化和反序列化操作 DRF源码s ...

  7. luoguP1006 传纸条

    题目描述 Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个 m" role="presentation& ...

  8. 虚拟机Ubuntu系统无法连接网络解决方案

    宿主机连接wifi,虚拟机无法联网 查看是否有网络图标 操作一: sudo service network-manager stopsudo rm /var/lib/NetworkManager/Ne ...

  9. halcon小结

    持更 应用范围 (罗列自官方帮助文档,以后有空了按照需求展开叙述) 1. 安全系统 2. 表面检测 3. 定位 4. 二维测量比较 5. 二维码识别 6. 二维位置定位 7. 二维物体识别 8. 光学 ...

  10. Spring AOP的使用及案例

    一.什么是AOP AOP(Aspect-Oriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.通过 ...