随着前后端分离架构和微服务架构的流行,我们使用Spring Boot来构建RESTful API项目的场景越来越多。通常我们的一个RESTful API就有可能要服务于多个不同的开发人员或开发团队:IOS开发、Android开发、Web开发甚至其他的后端服务等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法就是创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:
- 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。
- 随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
为了解决上面这样的问题,本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。具体效果如下图所示:
Swagger2的配置步骤如下:
一、引入依赖
pom.wml
<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>
二、引入配置类(并在生产环境屏蔽swagger)
@Configuration
@EnableSwagger2
public class SwaggerConfig{
@Autowired
ConfigService configService;
@Bean
public Docket customDocket() {
//这里环境也可以根据拿到启动参数进行判断(生产环境屏蔽swagger)
if(configService.getServerEnv() == ServerEnvEnum.ONLINE) {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfoOnline())
.select()
.paths(PathSelectors.none())//如果是线上环境,添加路径过滤,设置为全部都不符合
.build();
}else {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("XXX系统")
.description("XXX系统接口")
.license("")
.licenseUrl("")
.termsOfServiceUrl("")
.version("1.0.0")
.contact(new Contact("","", ""))
.build();
}
private ApiInfo apiInfoOnline() {
return new ApiInfoBuilder()
.title("")
.description("")
.license("")
.licenseUrl("")
.termsOfServiceUrl("")
.version("")
.contact(new Contact("","", ""))
.build();
}
}
启动项目后打开
http://localhost:8080/v2/api-docs
能看到 json 格式的接口描述
http://localhost:8080/swagger-ui.html
查看 ui 界面
Spring Boot中使用Swagger2构建强大的RESTful API文档
https://www.cnblogs.com/code-java/p/6419478.html
404
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Nov 24 19:57:13 CST 2016
There was an unexpected error (type=Not Found, status=404).
No message available
加上静态文件映射配置
package io.github.talelin.latticy.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@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/");
}
}
常用到的注解有:
- Api
- ApiModel
- ApiModelProperty
- ApiOperation
- ApiParam
- ApiResponse
- ApiResponses
- ResponseHeader
1. api标记
Api 用在类上,说明该类的作用。可以标记一个Controller类做为swagger 文档资源,使用方式:
属性名称 | 备注 |
---|---|
value | url的路径值 |
tags | 如果设置这个值、value的值会被覆盖 |
description | 对api资源的描述 |
basePath | 基本路径可以不配置 |
position | 如果配置多个Api 想改变显示的顺序位置 |
produces | For example, "application/json, application/xml" |
consumes | For example, "application/json, application/xml" |
protocols | Possible values: http, https, ws, wss. |
authorizations | 高级特性认证时配置 |
hidden | 配置为true 将在文档中隐藏 |
在SpringMvc中的配置如下:
@Controller
@RequestMapping(value = "/api/pet", produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE})
@Api(value = "/pet", description = "Operations about pets")
public class PetController {
}
2. ApiOperation标记
ApiOperation:用在方法上,说明方法的作用,每一个url资源的定义,使用方式:
@ApiOperation(
value = "Find purchase order by ID",
notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
response = Order,
tags = {"Pet Store"})
与Controller中的方法并列使用。
属性配置:
属性名称 | 备注 |
---|---|
value | url的路径值 |
tags | 如果设置这个值、value的值会被覆盖 |
description | 对api资源的描述 |
basePath | 基本路径可以不配置 |
position | 如果配置多个Api 想改变显示的顺序位置 |
produces | For example, "application/json, application/xml" |
consumes | For example, "application/json, application/xml" |
protocols | Possible values: http, https, ws, wss. |
authorizations | 高级特性认证时配置 |
hidden | 配置为true 将在文档中隐藏 |
response | 返回的对象 |
responseContainer | 这些对象是有效的 "List", "Set" or "Map".,其他无效 |
httpMethod | "GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" and "PATCH" |
code | http的状态码 默认 200 |
extensions | 扩展属性 |
在SpringMvc中的配置如下:
@RequestMapping(value = "/order/{orderId}", method = GET)
@ApiOperation(
value = "Find purchase order by ID",
notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
response = Order.class,
tags = { "Pet Store" })
public ResponseEntity<Order> getOrderById(@PathVariable("orderId") String orderId)
throws NotFoundException {
Order order = storeData.get(Long.valueOf(orderId));
if (null != order) {
return ok(order);
} else {
throw new NotFoundException(404, "Order not found");
}
}
3. ApiParam标记
ApiParam请求属性,使用方式:
public ResponseEntity<User> createUser(@RequestBody @ApiParam(value = "Created user object", required = true) User user)
与Controller中的方法并列使用。
属性配置:
属性名称 | 备注 |
---|---|
name | 属性名称 |
value | 属性值 |
defaultValue | 默认属性值 |
allowableValues | 可以不配置 |
required | 是否属性必填 |
access | 不过多描述 |
allowMultiple | 默认为false |
hidden | 隐藏该属性 |
example | 举例子 |
在SpringMvc中的配置如下:
public ResponseEntity<Order> getOrderById(
@ApiParam(value = "ID of pet that needs to be fetched", allowableValues = "range[1,5]", required = true)
@PathVariable("orderId") String orderId)
4. ApiResponse
ApiResponse:响应配置,使用方式:
@ApiResponse(code = 400, message = "Invalid user supplied")
与Controller中的方法并列使用。 属性配置:
属性名称 | 备注 |
---|---|
code | http的状态码 |
message | 描述 |
response | 默认响应类 Void |
reference | 参考ApiOperation中配置 |
responseHeaders | 参考 ResponseHeader 属性配置说明 |
responseContainer | 参考ApiOperation中配置 |
在SpringMvc中的配置如下:
@RequestMapping(value = "/order", method = POST)
@ApiOperation(value = "Place an order for a pet", response = Order.class)
@ApiResponses({ @ApiResponse(code = 400, message = "Invalid Order") })
public ResponseEntity<String> placeOrder(
@ApiParam(value = "order placed for purchasing the pet", required = true) Order order) {
storeData.add(order);
return ok("");
}
5. ApiResponses
ApiResponses:响应集配置,使用方式:
@ApiResponses({ @ApiResponse(code = 400, message = "Invalid Order") })
与Controller中的方法并列使用。 属性配置:
属性名称 | 备注 |
---|---|
value | 多个ApiResponse配置 |
在SpringMvc中的配置如下:
@RequestMapping(value = "/order", method = POST)
@ApiOperation(value = "Place an order for a pet", response = Order.class)
@ApiResponses({ @ApiResponse(code = 400, message = "Invalid Order") })
public ResponseEntity<String> placeOrder(
@ApiParam(value = "order placed for purchasing the pet", required = true) Order order) {
storeData.add(order);
return ok("");
}
6. ResponseHeader
响应头设置,使用方法
@ResponseHeader(name="head1",description="response head conf")
与Controller中的方法并列使用。 属性配置:
属性名称 | 备注 |
---|---|
name | 响应头名称 |
description | 头描述 |
response | 默认响应类 Void |
responseContainer | 参考ApiOperation中配置 |
在SpringMvc中的配置如下:
@ApiModel(description = "群组")
7. 其他
- @ApiImplicitParams:用在方法上包含一组参数说明;
- @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
- paramType:参数放在哪个地方
- name:参数代表的含义
- value:参数名称
- dataType: 参数类型,有String/int,无用
- required : 是否必要
- defaultValue:参数的默认值
- @ApiResponses:用于表示一组响应;
- @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息;
- code: 响应码(int型),可自定义
- message:状态码对应的响应信息
- @ApiModel:描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候;
- @ApiModelProperty:描述一个model的属性。
这部分引用自:https://www.jianshu.com/p/12f4394462d5
@ApiIgnore
屏蔽方法/参数/字段
@ApiIgnore 可用在方法上,类上,参数上
如果想在文档中屏蔽掉删除用户的接口(user/delete),那么只需要在删除用户的方法上加上 @ApiIgnore 即可。
1、屏蔽 delete 方法
@ApiIgnore
public boolean delete(@PathVariable("id") int id)
2、屏蔽 pageable 参数
@ApiOperation(value = "查询")
@ApiImplicitParams({ @ApiImplicitParam(name = "page", value = "当前页码"),
@ApiImplicitParam(name = "size", value = "每页数据条数"), })
@GetMapping("/user/query")
public APIResult<List<UserVO>> query(QueryVO queryVO, @ApiIgnore @PageableDefault Pageable pageable) {
List<ArchiveVO> page = service.queryUser(queryVO, pageable);
return RestOuts.ok(page);
}
导出 Swagger 文档
前提是项目已经开启了 swagger 依赖,能够导出 json 格式的 swagger 数据。
开启 swagger 后, http://localhost:8080/v2/api-docs 就是 json 数据地址,或者如果有 swagger-ui 界面,在主页左上角有此链接。
Swagger2Markup
Swagger2Markup 是 Github 上的一个开源项目。该项目主要用来将 Swagger 自动生成的文档转换成几种流行的格式以便于静态部署和使用,比如:AsciiDoc、Markdown、Confluence。
Swagger2Markup 项目是将 swagger 文档导出为其他格式的基础。
Swagger2Markup / swagger2markup
https://github.com/Swagger2Markup/swagger2markup
spring-swagger2markup-demo
我们将 swagger 导出为 pdf、html、markdown 格式都需要用到 Swagger2Markup 项目,但这个项目配置比较麻烦,所以官方给出了一个 demo 项目。
有了这个项目,我们只需要将自己的 swagger 数据保存为 json 文档,然后填入这个项目的配置属性,运行下 test 就好了。
Swagger2Markup / spring-swagger2markup-demo
https://github.com/Swagger2Markup/spring-swagger2markup-demo
导出为pdf或html
1 下载 Swagger2Markup / spring-swagger2markup-demo 项目,倒入为 maven 项目,等待 maven 下载依赖完成。
2 将自己的 swagger 数据保存为 api-docs.json
3 修改 spring-swagger2markup-demo 项目的 pom 文件,找到配置项 <swagger.input>
,改为自己 json 文档地址,绝对目录或相对目录都行。
4 执行 mvn test
命令,不报错的话,在项目下的 target/asciidoc 目录就能找到生成的文档。
其实,这里的 mvn test
包含两个步骤:
第一步将 json 转为 ASCIIDOC 格式。
第二步,将 ASCIIDOC 转为 pdf 和 html 格式。
使用中发现生成的 pdf 中有的中文字符不显示,但 html 是好的,可以先浏览器打开 html,再打印为 pdf 即可。
导出swagger2生成的文档
https://www.cnblogs.com/zeussbook/p/11091520.html
导出为markdown
默认情况下,Swagger2Markup 将 json 渲染为 asciidoc 基本文档格式,然后再转为 pdf 或 html 格式。
如果我们想转换为 markdown 格式,只需要修改一个参数即可
修改 spring-swagger2markup-demo 项目的 pom 文件,找到 swagger2markup-maven-plugin
插件的配置项 <swagger2markup.markupLanguage>
默认是 ASCIIDOC
改为 MARKDOWN
,然后执行 maven 插件的构建过程即可。
这次我们不需要执行 mvn test
只执行第一步即可。
Spring Boot 2.x基础教程:Swagger静态文档的生成
https://aijishu.com/a/1060000000017742
Failed to execute goal ‘convertSwagger2markup’
首次执行时报这个错,原因是 swagger2 导出的 json 文档不规范,少了几个必须的字段,导致 Swagger2Markup 执行失败。
1 首先,可以用官方的 json 文档试一下,如果没问题,就说明 spring-swagger2markup-demo 项目配置是没问题的。直接把数据粘贴百度的json规范的工具也可以。
官方json示例
https://petstore.swagger.io/v2/swagger.json
2 打开官方提供的一个 swagger 编辑器
https://editor.swagger.io/
把自己的 json 帖进去,右边会告诉你格式不准确的地方。
如下图,我这里生成的 json 就是缺了 title, version, license.name 属性,导致无法生成文档,加上就好了。
右边下面还会提示好多编码错误,不用管,只把缺字段的补上就好了。
Api2Doc
Swagger 比较臃肿,不太友好,偶然发现一个 Api2Doc 项目,和我们平常工作中用的 ShowDoc 文档非常相似,简洁又清晰。
terran4j/commons
https://github.com/terran4j/commons/tree/master/commons-api2doc
还在用 Swagger2 生成 Restful API 文档?来试试 Api2Doc 吧
https://my.oschina.net/u/3017144/blog/1679922
用Api2Doc代替Swagger2生成 Restful API 文档
https://www.jianshu.com/p/281df3ecd3b0