SpringBoot 利用 Swagger2 调试 API
系统环境:
- SpringBoot版本: 2.1.5
- Swagger版本: 2.9.2
- 示例Github地址:https://github.com/my-dlq/blog-example/tree/master/springboot/springboot-swagger-example
一、背景:
由于Spring Boot能够快速开发、便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。
这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发、Android开发或是Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:
- 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。
- 随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
为了解决上面这样的问题,本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到SpringBoot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。
二、Swagger简介:

Swagger 既是一款接口的文档在线自动生成软件,也是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。
三、Springboot 项目集成 Swagger2
1、Maven 引入 Swagger2 依赖
新建 Maven 项目,往其 pom.xml 中引入 Springboot 及 Swagger 相关 Jar。
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>club.mydlq</groupId> <artifactId>swagger-example-service</artifactId> <version>1.0.0</version> <name>swagger-example-service</name> <description>springboot swagger api example service</description>
<properties> <java.version>1.8</java.version> </properties>
<dependencies> <!-- SpringBoot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.5.RELEASE</version> </dependency> <!-- 引入Lombok,方便开发 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> <scope>provided</scope> </dependency> <!-- 引入Swagger相关依赖 --> <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> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>2、创建 Swagger 配置类
创建 Swagger 配置类,设置 Swagger 文档信息。
注意:配置中不要设置 “groupName” 参数,否则可能无法文档聚合。
import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.service.ApiInfo;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;
@Configurationpublic class SwaggerConfig {
@Value("${swagger.enable}") private boolean swaggerEnable; // 读取配置文件中 swagger 开关参数的值
@Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .enable(swaggerEnable) // 是否启用 Swagger .apiInfo(apiInfo()) //.groupName("swagger-example-service") // 项目组名 .select() // 选择那些路径和api会生成document .apis(RequestHandlerSelectors.any()) // 对所有api进行监控 .paths(PathSelectors.any()) // 对所有路径进行监控 .paths(Predicates.not(PathSelectors.regex("/error.*")))//错误路径不监控 .paths(Predicates.not(PathSelectors.regex("/actuator.*")))//actuator路径跳过 .build(); }
private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("swagger-example-service") // 文档标题 .description("This is a swagger project.") // 文档描述 .version("1.0.0") // 文档版本 .build(); }
}3、配置文件中添加 swagger 开关参数
配置文件 application.yml 中添加 swagger.enable 配置参数,方便控制是否开启 swagger,一般在生产环境中我们会设置这个值为 false。
spring: application: name: swagger-example-service
### Swagger开关配置参数swagger: enable: true4、创建 user 实体类
为了方便测试,这里创建一个 User 实体类,并且利用 Swagger 的 @ApiModelProperty 注解对实体类某个属性描述,方便Swagger文档中描述实体类中信息。
import io.swagger.annotations.ApiModelProperty;import java.util.Date;
public class User { // @ApiModelProperty:用于描述字段信息 @ApiModelProperty(value = "姓名", required = true) private String name; @ApiModelProperty(value = "性别", required = true) private String sex; @ApiModelProperty(value = "岁数", required = true) private Integer age; @ApiModelProperty(value = "生日") private Date birthday;}5、创建示例 Controller 接口
创建一个 Controller 类,且运用 Swagger 注解,将接口信息详细描述。
这里用了几个 Swagger 注解,分别为:
- @Api:对整个 Controller 接口信息的描述
- @ApiOperation:对某个接口信息进行描述
- @ApiResponses:对某个反馈信息状态码进行描述
- @ApiParam:对某个接口参数进行描述
import io.swagger.annotations.*;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.util.MimeTypeUtils;import org.springframework.web.bind.annotation.*;
@RestController@Api(tags = "Example Controller Document")public class ExampleController {
@GetMapping(value = "/example") @ApiOperation(value = "获取示例信息", notes = "用 Get 请求发送,获取示例设置的字符串信息。") @ApiResponses({ @ApiResponse(code = 200, message = "成功处理请求"), @ApiResponse(code = 401, message = "没有权限访问该服务"), @ApiResponse(code = 403, message = "权限不足无法访问该服务"), @ApiResponse(code = 404, message = "未发现该微服务"), @ApiResponse(code = 500, message = "服务器内部错误") }) public String getExample( @ApiParam(value = "输入一个 Key") @RequestParam(value = "key") String key, @ApiParam(value = "输入一个 Value", required = true) @RequestParam(value = "value") String value) { return "The value you enter is:" + key + ":" + value; }
@PostMapping(value = "/example") @ApiOperation(value = "发送示例信息", notes = "Post方法,发送示例信息") @ApiResponses({ @ApiResponse(code = 200, message = "成功处理请求"), @ApiResponse(code = 401, message = "没有权限访问该服务"), @ApiResponse(code = 403, message = "权限不足无法访问该服务"), @ApiResponse(code = 404, message = "未发现该微服务"), @ApiResponse(code = 500, message = "服务器内部错误") }) public ResponseEntity<User> postExample(@ApiParam(value = "用户信息") @RequestBody User user) { // 设置状态码,且设置默认值为200 HttpStatus httpStatus = HttpStatus.OK; return new ResponseEntity<User>(user,httpStatus); }
@PutMapping(value = "/example") @ApiResponses({ @ApiResponse(code = 200, message = "成功处理请求"), @ApiResponse(code = 201, message = "被创建"), @ApiResponse(code = 401, message = "没有权限访问该服务"), @ApiResponse(code = 403, message = "权限不足无法访问该服务"), @ApiResponse(code = 404, message = "未发现该微服务"), @ApiResponse(code = 500, message = "服务器内部错误") }) @ApiOperation(value = "修改示例信息", notes = "Put方法,修改示例信息") public ResponseEntity<User> putExample(@ApiParam(value = "用户信息") @RequestBody User user) { // 设置状态码,且设置默认值为200 HttpStatus httpStatus = HttpStatus.OK; // 设置 Headers HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add(HttpHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON_VALUE); // 错误就发送 500 错误 if (user == null) { httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; } return new ResponseEntity<User>(user, httpHeaders, httpStatus); }
@DeleteMapping(value = "/example/{key}") @ApiOperation(value = "删除示例信息", notes = "Delete方法,删除示例信息。") @ApiResponses({ @ApiResponse(code = 200, message = "成功处理请求"), @ApiResponse(code = 204, message = "成功处理请求,服务器无返回内容"), @ApiResponse(code = 401, message = "没有权限访问该服务"), @ApiResponse(code = 403, message = "权限不足无法访问该服务"), @ApiResponse(code = 404, message = "未发现该微服务"), @ApiResponse(code = 500, message = "服务器内部错误") }) public void deleteExample(@ApiParam(value = "输入一个 Key") @PathVariable(value = "key") String key) { System.out.println("delete info " + key); }
}6、启动类加上注解 @EnableSwagger2
在启动类上加上 @EnableSwagger2 注解以开启 Swagger2。
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2@SpringBootApplicationpublic class Application {
public static void main(String[] args) { SpringApplication.run(Application.class, args); }
}7、访问 Swagger API
项目创建完成后,本地启动然后输入地址 http://localhost:8080/v2/api-docs,可以看见 Swagger API 接口返回的 JSON 信息。
{ "swagger": "2.0", "info": { "description": "This is a swagger project.", "version": "1.0.0", "title": "swagger-example-service" }, "host": "localhost:8080", "basePath": "/", "tags": [ { "name": "Example Controller Doc", "description": "Example Controller" }, { "name": "basic-error-controller", "description": "Basic Error Controller" } ], "paths": { "/error": { "get": { "tags": [ "basic-error-controller" ], "summary": "error", "operationId": "errorUsingGET", "produces": [ "*/*" ], "responses": { "200": { "description": "OK", "schema": { "type": "object", "additionalProperties": { "type": "object" } } }, "401": { "description": "Unauthorized" }, "403": { "description": "Forbidden" }, "404": { "description": "Not Found" } }......8、访问 Swagger UI
Swagger 除了有 Json 形式的数据外,也有对 Json 数据页面化展示的 Swagger UI,在开始的时候 pom.xml 就已经引入该 Swagger UI 相关 Jar,所以这里我们将项目启动后,输入地址 http://localhost:8080/swagger-ui.html 就能访问到 Swagger 接口信息。

