在本系列的上一篇文章中, 给大家演示在Spring Boot中如何对 Restful 服务接口输入的数据进行校验。本文将继续深入,演示如何使用 Swagger 生成 Restful 服务接口的文档并用 Swagger 生成的页面对 API 进行测试。

在微服务开发中,各个微服务开发者需要向使用者提供 API 文档,传统习惯用 Word 文档。但 Word 文档比较容易出现的问题是:

  1. 文档和代码不同步或文档有多个版本,导致看到文档也不知道改如何使用?
  2. 不能在网页上测试 API,而需要安装一些工具来测试,特别是对于非 GET 方法的 API

Swagger 解决了以上的问题,Spring Boot 提供了非常简单的方法集成 Swagger 的具体实现。下面就带大家来体验一下:

基础设置

增加依赖库,修改 pom.xml 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</dependency>
<!-- End Swagger -->

然后新建一个 Spring Boot 的配置类,用来配置 Swagger。 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Configuration
public class SwaggerCofnig extends WebMvcConfigurationSupport {

@Bean
public Docket apis() {
return new Docket(DocumentationType.SWAGGER_2);
}

@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}

}

最后,在应用的启动类上加入新的注解 @@EnableSwagger2, 如下:

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableSwagger2
public class TodoApplication {

public static void main(String[] args) {
SpringApplication.run(TodoApplication.class, args);
}

}

现在,运行程序,访问 localhost:8080/v2/api-docs, 我们可以得到 Swagger 为应用生成的 api 描述, json 格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
{
"swagger": "2.0",
"info": {
"description": "Api Documentation",
"version": "1.0",
"title": "Api Documentation",
"termsOfService": "urn:tos",
"contact": {},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0"
}
},
"host": "localhost:8080",
"basePath": "/",
"tags": [{
"name": "basic-error-controller",
"description": "Basic Error Controller"
}, {
"name": "todo-api",
"description": "Todo Api"
}],
"paths": {
...
"/todo": {
"get": {
"tags": ["todo-api"],
"summary": "getTodoList",
"operationId": "getTodoListUsingGET",
"produces": ["*/*"],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ApiResult"
}
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
}
},
"post": {
"tags": ["todo-api"],
"summary": "addTodo",
"operationId": "addTodoUsingPOST",
"consumes": ["application/json"],
"produces": ["*/*"],
"parameters": [{
"in": "body",
"name": "todo",
"description": "todo",
"required": true,
"schema": {
"$ref": "#/definitions/Todo"
}
}],
},
...

因为内容比较多,这里就不全部列出来了。不过可以看到,Swagger 不仅生成了应用的API说明,也生成了 Spring Boot 默认的系统 API 的说明。

当然,用 json 的方式查看对开发者来说太麻烦。有没有更好的查看方式呢?

访问 localhost:8080/swagger-ui.html, 就能看到漂亮的文档了。

展开 todo-api

还有API中用到的 Model 也生成了文档,真是太方便了。

只生成应用自身的API

看了上面 Swagger 输出的文档,包含了 Spring Boot 框架的 API,也包括了应用自己的 API, 看起来有点乱,而且通常我们并不关心框架的API, 能不能限制只生成应用自身的 API 呢?当然可以,通过修改 Swagger 的配置信息可以达到这个目的。

打开配置类 SwaggerCofnig.java, 在生成 Docket 对象后调用 select 方法进行筛选,下面我们通过包名和URL路径名来筛选:

1
2
3
4
5
6
7
8
@Bean
public Docket apis() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("cn.com.hohistar.tutorial.springboot.starter"))
.paths(regex("/todo.*"))
.build();
}

修改好以后,再次运行程序,打开 localhost:8080/swagger-ui.html

可以看到,只剩下应用的 API 和相关 Model 了。

测试API

实际上,通过 Swagger 生成的 HTML 页面,我们不仅可以查看 API 的信息,还可以自己在页面上测试 API, 这简直不要太方便了! 以往这可是要用 curl 和 Postman 来解决的。

添加应用信息

现在,让我们来改一下 Swagger 生成页面中的应用信息。还是修改 Swagger 配置类,加入联系人和应用信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Configuration
@EnableSwagger2
public class SwaggerCofnig extends WebMvcConfigurationSupport {

public static final Contact DEFAULT_CONTACT = new Contact(
"Jini", "https://www.mls-tech.info", "mls-tech@qq.com");

public static final ApiInfo DEFAULT_API_INFO = new ApiInfoBuilder()
.title("Todo API")
.description("Spring Boot Getting Start - Todo API")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
.contact(DEFAULT_CONTACT)
.build();

@Bean
public Docket apis() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("cn.com.hohistar.tutorial.springboot.starter"))
.paths(regex("/todo.*"))
.build()
.apiInfo(DEFAULT_API_INFO);
}

@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}

}

关键的改变在代码24行,在这里为 Docket 加入了自定义的应用信息。运行结果如图:

为接口和模型添加信息

如果我们还想对 API 或相关 Model 提供一些附加的说明,这个 Swagger 也提供了支持,

  1. 添加 API 说明, 打开 TodoApi.java 文件, 在方法定义上加入 @ApiOperation 注解。
1
2
3
4
5
6
7
8
9
10
11
12
@PostMapping
@ApiOperation(value = "add a todo", notes = "在新增时,id是不需要的,title is requried.")
public ApiResult addTodo(@Valid @RequestBody Todo todo) {

ApiResult.ApiResultBuilder builder = ApiResult.builder().succ(false).build().toBuilder();

todoBiz.addTodo(todo);

builder.succ(true);

return builder.build();
}
  1. 添加 Model 说明, 打开 Todo.java 文件, 在类定义上加入 @ApiModel 注解,在需要添加说明的属性上可以添加 ApiModelProperty 注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@ApiModel(description = "All details about the Todo.")
public class Todo {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@ApiModelProperty(notes = "唯一编码,有系统自动生成")
private Integer id;

@NotNull
@ApiModelProperty(notes = "title is required.")
private String title;

private String desc;

}

再次启动程序,可以看到新增加的说明。

TAGS