Spring Boot 2.X(十五):集成 Swagger2 开发 API 文档(在线+离线)
前言
相信很多后端开发在项目中都会碰到要写 api 文档,不管是给前端、移动端等提供更好的对接,还是以后为了以后交接方便,都会要求写 api 文档。
而手写 api 文档的话有诸多痛点:
- 文档更新的时候,需要再次发送给对接人
- 接口太对,手写文档很难管理
- 接口返回的结果不明确
- 不能直接在线测试接口,通常需要使用工具,如 postman 等
Swagger 就很好的解决了这个问题。
Swagger 简介
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。
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 格式文件。
完整代码
Spring Boot 2.X(十五):集成 Swagger2 开发 API 文档(在线+离线)的更多相关文章
- ant design pro (十五)advanced 使用 API 文档工具
一.概述 原文地址:https://pro.ant.design/docs/api-doc-cn 在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难 ...
- Spring Boot中使用Swagger2构建API文档
程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...
- 使用springfox+swagger2书写API文档(十八)
使用springfox+swagger2书写API文档 springfox是通过注解的形式自动生成API文档,利用它,可以很方便的书写restful API,swagger主要用于展示springfo ...
- 白话SpringCloud | 第十一章:路由网关(Zuul):利用swagger2聚合API文档
前言 通过之前的两篇文章,可以简单的搭建一个路由网关了.而我们知道,现在都奉行前后端分离开发,前后端开发的沟通成本就增加了,所以一般上我们都是通过swagger进行api文档生成的.现在由于使用了统一 ...
- SpringBoot+rest接口+swagger2生成API文档+validator+mybatis+aop+国际化
代码地址:JillWen_SpringBootDemo mybatis 1. 添加依赖: <dependency> <groupId>org.mybatis.spring.bo ...
- spring boot 2.x 系列——spring-boot 集成 Swagger2 打造在线接口文档
文章目录 一.Springfox 与 Swagger 简介 1.1 Springfox 1.2 Swagger 1.3 OpenApi.Swagger.Springfox的关系 二.spring bo ...
- 学习Spring Boot:(六) 集成Swagger2
前言 Swagger是用来描述和文档化RESTful API的一个项目.Swagger Spec是一套规范,定义了该如何去描述一个RESTful API.类似的项目还有RAML.API Bluepri ...
- Spring Boot 整合Swagger2构建API文档
1.pom.xml中引入依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>spri ...
- Spring Boot 系列(七)Swagger2-生成RESTful接口文档
Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服 ...
随机推荐
- Spring Cloud Gateway 使用
简介 Spring Cloud Gateway是Spring Cloud官方推出的网关框架,网关作为流量入口,在微服务系统中有着十分重要的作用,常用功能包括:鉴权.路由转发.熔断.限流等. Sprin ...
- Angular 路由守卫
1. 路由 Angular路由: 可以控制页面跳转:可以在多视图间切换: 2. 路由守卫 Angular路由守卫: 在进入或离开某路由时,用于判断是否可以离开.进入某路由::: return true ...
- 1. jQuery中的DOM操作
1)查找节点 通过jQuery选择器来完成 2)创建节点 创建元素节点:var newTd = $("<td></td>") 创建文本节点:在创建元素节点时 ...
- Java 2019 生态圈使用报告,这结果你赞同吗?
这是国外一机构调查了 7000 名开发者得出来的 Java 2019 年生态圈工具使用报告,主要调查了 Java 版本.开发框架.web 服务器等使用情况.虽然只有 7000 名开发者参与调查,这数目 ...
- 02-28 scikit-learn库之线朴素贝叶斯
目录 scikit-learn库之朴素贝叶斯 一.MultinomialNB 1.1 使用场景 1.2 代码 1.3 参数详解 1.4 属性 1.5 方法 二.GaussianNB 三.Bernoul ...
- DRF框架学习总结
DRF框架安装配置及其功能概述 Django与DRF 源码视图解析 DRF框架序列化和返序列化 DRF框架serializers中ModelSerializer类简化序列化和反序列化操作 DRF源码s ...
- luoguP1006 传纸条
题目描述 Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个 m" role="presentation& ...
- 虚拟机Ubuntu系统无法连接网络解决方案
宿主机连接wifi,虚拟机无法联网 查看是否有网络图标 操作一: sudo service network-manager stopsudo rm /var/lib/NetworkManager/Ne ...
- halcon小结
持更 应用范围 (罗列自官方帮助文档,以后有空了按照需求展开叙述) 1. 安全系统 2. 表面检测 3. 定位 4. 二维测量比较 5. 二维码识别 6. 二维位置定位 7. 二维物体识别 8. 光学 ...
- Spring AOP的使用及案例
一.什么是AOP AOP(Aspect-Oriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.通过 ...