在本系列的上一篇文章中, 给大家演示在Spring Boot中如何对 Restful 服务接口输入的数据进行校验。本文将继续深入,演示如何使用 Swagger 生成 Restful 服务接口的文档并用 Swagger 生成的页面对 API 进行测试。
在微服务开发中,各个微服务开发者需要向使用者提供 API 文档,传统习惯用 Word 文档。但 Word 文档比较容易出现的问题是:
- 文档和代码不同步或文档有多个版本,导致看到文档也不知道改如何使用?
- 不能在网页上测试 API,而需要安装一些工具来测试,特别是对于非 GET 方法的 API
Swagger 解决了以上的问题,Spring Boot 提供了非常简单的方法集成 Swagger 的具体实现。下面就带大家来体验一下:
基础设置
增加依赖库,修改 pom.xml 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <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>
|
然后新建一个 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 也提供了支持,
- 添加 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(); }
|
- 添加 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;
}
|
再次启动程序,可以看到新增加的说明。