SpringBoot系列: 使用 Swagger 生成 API 文档
SpringBoot非常适合开发 Restful API程序, 我们都知道为API文档非常重要, 但要维护好难度也很大, 原因有:
1. API文档如何能被方便地找到? 以文件的形式编写API文档都有这个问题, 使用在线 Wiki 等知识平台部分地能解决这个问题.
2. API文档经常过期. API 接口不断地被改进, 有些项目组使用Word软件编写API文档, 因版本管理难度大, 最后往往是API文档严重过时. 使用 Markdown 格式编写会好一些.
Swagger 是一个非常好的工具, 用的好能解决上面的两个顽疾. Swagger解决方法也很直接:
1. 我们的 Restful API项目自动会暴露一个Swagger UI endpoint 来呈现 API 文档, 访问 http://localhost:8080/swagger-ui.html 即可查看API文档.
2. API 文档是以 Java 注解的形式埋点在代码中, 我们修改Rest API的同时, 顺便就能修改相应的文档注解, Release 新版API.
Swagger 文档主要包括:
1. 一个 Docket 摘要信息
2. 多个 Model 类的说明
3. 多个 Controller 类的说明
SpringBoot 可以使用 SpringFox 直接集成 Swagger 功能, SpringFox同时支持 Swagger1.2 和 Swagger2, 推荐使用 Swagger2, 相关文档 http://springfox.github.io/springfox/docs/current/#springfox-spring-mvc-and-spring-boot
====================================
Swagger常用注解
====================================
我们项目在增加了 @EnableSwagger2 之后, swagger 会很为几乎所有的自定义类生成文档信息(当然 swagger 内置一个 ignore 清单), 背后的技术可能是 reflection 吧, 可以想象通过发射机制生成的文档就是一个代码的缩略版, 用处不大.
要想丰富 swagger 文档, 需要使用它提供的一系列注解, 通过注解表明生成高质量的Api文档,包括接口名、请求方法、参数、返回信息的等等.
@ApiModel: 修饰 Pojo 类.
@ApiModelProperty: 修饰 Pojo 类属性
@Api: 修饰Controller 类, 说明该 controller 的作用
@ApiOperation: 描述 controller类的一个方法, 说明该方法的作用
@ApiImplicitParams: Api方法的参数注解, 通常包含多个 @ApiImplicitParam 注解.
@ApiImplicitParam: 一个具体参数的注解, 该注解需要放在 @ApiImplicitParams 注解内, 该注解的选项有:
1. paramType 选项: 用来说明参数应该被放置的地方, 有 query/header/pathy/body/form 等取值, query 取值适合于 @RequstParam 参数, header取值适合于@RequestHeader参数, path取值适合于@PathVariable参数, body 取值适合于 @RequestBody 参数.
2. name 选项: 参数名
3. dataType 选项: 参数类型
4. required 选项: 是否必须传
5. value 选项: 参数值
6. defaultValue 选项: 参数默认值
@ApiResponses: 为controller方法增加 HTTP响应整体描述, 通常包含多个 @ApiResponse 注解.
@ApiResponse: HTTP响应其中一个描述, 该注解需要放在 @ApiResponses 注解内, 该注解的选项有:
1. code 选项: 即 httpCode 或 httpStatus, 比如 200 等.
2. message 选项, code 对应的自定义文字说明.
@ApiIgnore: 让 Swagger 忽略被本注解标注的类/方法/属性. (经我的测试, 2.9.2版不能忽略类).
====================================
pom.xml
====================================
增加 springfox 两个依赖包.
<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>
====================================
新建一个 SwaggerConfig 配置类
====================================
在项目中需要增加一个 Swagger Config 类, 该类需要加上 @EnableSwagger2 注解, 在该类中需要声明一个 Docket bean, Docket 这个词我理解应该是 DocumentLet 的缩写, 相当于API文档的摘要信息.
@Configuration
@EnableSwagger2
public class SwaggerConfig { /*
* Docket 是 DocumentLet 的缩写, 相当于摘要
*/
@Bean
public Docket createRestApi() {
Docket docklet = new Docket(DocumentationType.SWAGGER_2).apiInfo(metaData())
.select()
// apis() 作用是通过 basePackage 或 withClassAnnotation 来指定swagger扫描的类的范围
.apis(RequestHandlerSelectors.basePackage("com.example.demo"))
// paths() 是通过路径的方式来指定swagger扫描的类的范围
.paths(PathSelectors.any())
.build(); return docklet;
} private ApiInfo metaData() {
return new ApiInfoBuilder().title("Spring Boot中使用Swagger2构建RESTful APIs")
.description("学习使用 Swagger2 ")
.contact(new Contact("author name", "http://about.me", "email@email.com"))
.version("1.0")
.build();
}
} /*
*
* //如果集成了 Spring Security , 需要加一个Spring Security配置类允许访问 swagger 相关资源
*
* @Configuration public class SpringSecConfig extends
* WebSecurityConfigurerAdapter {
*
* @Override protected void configure(HttpSecurity httpSecurity) throws
* Exception {
* httpSecurity.authorizeRequests().antMatchers("/","/swagger-resources").
* permitAll(); httpSecurity.csrf().disable();
* httpSecurity.headers().frameOptions().disable(); } }
*/
====================================
Pojo 类
====================================
Pojo 类加上 @ApiModel 注解, 仅仅是能增加点 description 选项. 每个属性可以用 @ApiModelProperty 注解.
@ApiModel(description="Product model object")
class Product {
@ApiModelProperty(notes = "The application-specific product id", dataType = "String")
private String productId;
@ApiModelProperty(notes = "The product description")
private String description;
@ApiModelProperty(notes = "The price of the product", required = true, dataType = "Decimal")
private BigDecimal price; public Product() {
} public static Product getEmptyProduct() {
Product product = new Product();
product.setProductId("===empty===");
return product;
} public Product(String productId, String description, BigDecimal price) {
this.productId = productId;
this.description = description;
this.price = price;
} //省略 getter/setter
}
====================================
Controller 类
====================================
Controller 类是 API 文档的重点, 使用 @Api 注解类, 使用 @ApiOperation/@ApiResponses/@ApiImplicitParams 来注解方法.
@RestController
@RequestMapping("/product")
@Api(tags = "Product Controller", description = "Operations pertaining to products in online store")
class ProductController {
private ProductService productService; @Autowired
void setProductService(ProductService productService) {
this.productService = productService;
} @ApiOperation(value = "view of list of available products", response = Iterable.class)
@ApiResponses(value = { @ApiResponse(code = 200, message = "Sucessfully retrieve list"),
@ApiResponse(code = 401, message = "You are not authorized to view the resource"),
@ApiResponse(code = 403, message = "Accessing the resource you were trying to reach is forbidden") })
@RequestMapping(value = "/list", method = RequestMethod.GET, produces = "application/json")
public Iterable<Product> list(Model model) {
return productService.listAllProducts();
} @ApiOperation(value = "Search a product by productId", response = Product.class)
@RequestMapping(value = "/show/{productId}", method = RequestMethod.GET, produces = "application/json")
public Product showProduct(@PathVariable String productId, Model model) {
Optional<Product> optional = productService.getProductById(productId);
return optional.orElse(Product.getEmptyProduct());
}
}
====================================
Service 类
====================================
这里 Service 有一个 ProductService 接口和 ProductServiceImpl 实现类, 它们和 swagger 没有关系.
/*
* Product Service 接口
*/
interface ProductService {
Iterable<Product> listAllProducts(); Optional<Product> getProductById(String productId); Product saveProduct(Product product); void deleteProduct(String productId);
} /*
* Product Service 的实现类
*/
@Service
@Scope("singleton")
class ProductServiceImpl implements ProductService {
private static List<Product> productStore = new ArrayList<Product>(); public ProductServiceImpl() {
productStore.add(new Product("Product1", "About Product1", new BigDecimal("1")));
productStore.add(new Product("Product2", "About Product2", new BigDecimal("2")));
productStore.add(new Product("Product3", "About Product3", new BigDecimal("3")));
} @Override
public Iterable<Product> listAllProducts() {
return productStore;
} @Override
public Product saveProduct(Product product) {
deleteProduct(product.getProductId());
productStore.add(product);
return product;
} @Override
public Optional<Product> getProductById(String productId) {
return productStore.stream()
.filter(p -> productId.equals(p.getProductId()))
.findFirst();
} @Override
public void deleteProduct(String productId) {
productStore.removeIf(p -> p.getProductId()
.equals(productId));
}
}
====================================
测试效果
====================================
访问 http://localhost:8080/swagger-ui.html

====================================
参考
====================================
https://springframework.guru/spring-boot-restful-api-documentation-with-swagger-2/
https://www.jianshu.com/p/8033ef83a8ed
https://www.jianshu.com/p/be05aa96fd29
SpringBoot系列: 使用 Swagger 生成 API 文档的更多相关文章
- .Net Core 3.1 WebApi使用Swagger生成Api文档
用swagger生成Api文档 1.安装Swashbuckle.AspNetCore 右键单击"解决方案资源管理器" > "管理 NuGet 包"中的项目 ...
- springboot+mybatis-puls利用swagger构建api文档
项目开发常采用前后端分离的方式.前后端通过API进行交互,在Swagger UI中,前后端人员能够直观预览并且测试API,方便前后端人员同步开发. 在SpringBoot中集成swagger,步骤如下 ...
- 12 Django Rest Swagger生成api文档
01-简介 Swagger:是一个规范和完整的框架,用于生成.描述.调用和可视化RESTful风格的Web服务.总体目标是使客户端和文件系统源代码作为服务器以同样的速度来更新.当接口有变动时,对应的接 ...
- SpringBoot结合Swagger2自动生成api文档
首先在pom.xml中添加如下依赖,其它web,lombok等依赖自行添加 <dependency> <groupId>io.springfox</groupId> ...
- SpringBoot+rest接口+swagger2生成API文档+validator+mybatis+aop+国际化
代码地址:JillWen_SpringBootDemo mybatis 1. 添加依赖: <dependency> <groupId>org.mybatis.spring.bo ...
- ASP.NET Core 3.0 WebApi中使用Swagger生成API文档简介
参考地址,官网:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/getting-started-with-swashbuckle?view ...
- Laravel(PHP)使用Swagger生成API文档不完全指南 - 基本概念和环境搭建 - 简书
在PHPer中,很多人听说过Swagger,部分人知道Swagger是用来做API文档的,然而只有少数人真正知道怎么正确使用Swagger,因为PHP界和Swagger相关的资料实在是太少了.所以鄙人 ...
- 基于.NetCore3.1搭建项目系列 —— 使用Swagger做Api文档 (上篇)
前言 为什么在开发中,接口文档越来越成为前后端开发人员沟通的枢纽呢? 随着业务的发张,项目越来越多,而对于支撑整个项目架构体系而言,我们对系统业务的水平拆分,垂直分层,让业务系统更加清晰,从而产生一系 ...
- 基于.NetCore3.1搭建项目系列 —— 使用Swagger做Api文档 (下篇)
前言 回顾上一篇文章<使用Swagger做Api文档 >,文中介绍了在.net core 3.1中,利用Swagger轻量级框架,如何引入程序包,配置服务,注册中间件,一步一步的实现,最终 ...
随机推荐
- LeetCode算法题-Convert BST to Greater Tree(Java实现)
这是悦乐书的第255次更新,第268篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第122题(顺位题号是538).给定二进制搜索树(BST),将其转换为更大树,使原始BS ...
- 使用Java反射优化多个方法调用
有段时间没来写博客了,心里一直念叨空了来,今天有时间来记录一篇.前段时间领导提出优化部分系统模块,根据业务要求系统中有很多产品,产品下面有N个指标,一个指标就对应一个方法,所以系统代码中就是这样一个情 ...
- 爬虫实例系列一(requests)
一 爬虫简介 ''' 爬虫:通过编写程序,模拟浏览器上网,让其去互联网上爬取数据的过程 分类: 通用爬虫:爬取全部的页面数据 聚焦爬虫:抓取页面中局部数据 增量式爬虫:爬取网站中更新出的数据 反爬机制 ...
- yuan 老师 之 Django
前端: 1.前端基础之JavaScript https://www.cnblogs.com/yuanchenqi/articles/6893904.html 2.前端基础之jQuery https:/ ...
- kubernetes-核心资源之Ingress
1.Ingress 在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的.为了使外部的应用能够访问集群内的服务,在Kubernetes中可以通过Node ...
- future builder
import 'package:flutter/material.dart';import 'dart:convert';import 'package:http/http.dart' as http ...
- Linux内存管理 (12)反向映射RMAP
专题:Linux内存管理专题 关键词:RMAP.VMA.AV.AVC. 所谓反向映射是相对于从虚拟地址到物理地址的映射,反向映射是从物理页面到虚拟地址空间VMA的反向映射. RMAP能否实现的基础是通 ...
- Golang 入门系列(五)GO语言中的面向对象
前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/ ...
- oracle--数据筛选
一:当统一社会信用代码或者工商注册号两个字段中,有的时候只有一个字段含有数据,但是所取的值必须要拥有字段,这个时候,语句为下: select t.entname, case when t.unisci ...
- Python的数据库操作
使用原生SQL语句进行对数据库操作,可完成数据库表的建立和删除,及数据表内容的增删改查操作等.其可操作性很强,如可以直接使用“show databases”.“show tables”等语句进行表格之 ...