Spring boot :使用 Swagger 2 构建 RESTful APIs
1.美图
2.什么是 Swagger
Swagger 是一系列列 RESTful API 的⼯具,通过 Swagger 可以获得项⽬的一种交互式⽂档,客户端 SDK 的⾃动⽣生成等功能。
Swagger 的⽬标是为 REST APIs 定义⼀个标准的、与语⾔⽆关的接口,使⼈和计算机在看不到源码或者看不到文档或者不能通过网络流量检测的情况下,能发现和理解各种服务的功能。当服务通过 Swagger 定义,消费者就能与远程的服务互动通过少量的实现逻辑。类似于低级编程接口, Swagger 去掉了了调⽤服务时的很多猜测。
Swagger(丝袜哥)是世界上最流行的 API 表达工具。
Swagger 是⼀个简单但功能强大的 API 表达工具。它具有地球上最⼤的 API 工具⽣态系统,数以千计的开发人员,使⽤用⼏乎所有的现代编程语言,都在支持和使⽤用 Swagger。使⽤用 Swagger ⽣成 API,我们可以得到交
互式⽂档,自动生成代码的 SDK 以及 API 的发现特性等。
使⽤用 Spring Boot 集成 Swagger 的理理念是,使⽤注解来标记出需要在 API ⽂档中展示的信息, Swagger 会根据项⽬中标记的注解来⽣成对应的 API ⽂档。 Swagger 被号称世界上最流行的 API 工具,它提供了了 API
管理的全套解决方案, API 文档管理需要考虑的因素基本都包含,这里将讲解最常⽤的定制内容。
Spring Boot 集成 Swagger 2.X 很简单,需要引⼊入依赖并做基础配置即可.
2.案例
下⾯面我们来感受⼀一下。引入
<project>
<properties>
<!-- 语言环境 相关 -->
<jdk.version>1.8</jdk.version>
<!-- sparing 相关 -->
<spring.boot.version>2.1.2.RELEASE</spring.boot.version>
<spring.test.version>4.3.8.RELEASE</spring.test.version>
<springfox-swagger.version>2.8.0</springfox-swagger.version>
<!-- 工具 相关 -->
<commons-lang3.version>3.7</commons-lang3.version>
<commons-logging.version>1.2</commons-logging.version>
<lombok.version>1.18.2</lombok.version>
<fastjson.version>1.2.49</fastjson.version>
<jackson.version>2.6.6</jackson.version>
</properties>
<dependencies>
<!-- sparing 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<!-- 工具 相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- 数澜其他组件 相关-->
<!-- 当前项目 相关 -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.dtwave.meteor.connector.web.MeteorConnector</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3.创建 SwaggerConfig 配置类
package com.spring.boot.test.config;
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.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Description:
*
* @author lcc
* @version 1.0
* @date 2019/12/27 5:29 下午
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
// ⾃自⾏行行修改为⾃自⼰己的包路路径
.apis(RequestHandlerSelectors.basePackage("com.spring.boot.test"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("客户管理理")
.description("客户管理理中⼼心 API 1.0 操作⽂文档")
//服务条款⽹网址
.termsOfServiceUrl("http://www.ityouknow.com/")
.version("1.0")
.contact(new Contact("纯洁的微笑", "http://www.ityouknow.com/", "aaa@qq.com"))
.build();
}
}
在 SwaggerConfig 的类上添加两个注解:
- @Configuration,启动时加载此类
- @EnableSwagger2,表示此项⽬目启⽤用 Swagger API ⽂文档
此⽅方法使⽤用 @Bean
,在启动时初始化,返回实例例 Docket(Swagger API
摘要),这⾥里里需要注意的是.apis(RequestHandlerSelectors.basePackage("com.neo.xxx"))
指定需要扫描的包路路径,只有此路路径下的Controller 类才会⾃自动⽣生成 Swagger API ⽂文档。
这块配置相对重要⼀一些,主要配置⻚页⾯面展示的基本信息包括,标题、描述、版本、服务条款、联系⽅方式等,
查看 ApiInfo 类的源码还会发现⽀支持 license 配置等。
public class ApiInfo {
public static final Contact DEFAULT_CONTACT = new Contact("", "", "");
public static final ApiInfo DEFAULT;
private final String version;
private final String title;
private final String description;
private final String termsOfServiceUrl;
private final String license;
private final String licenseUrl;
private final Contact contact;
private final List<VendorExtension> vendorExtensions;
....
}
4.主要类
package com.spring.boot.test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import lombok.extern.slf4j.Slf4j;
/**
* Description:
*
* @author lcc
* @version 1.0
* @date 2019/12/27 5:39 下午
*/
@Slf4j
@SpringBootApplication
@ComponentScan(basePackages = {"com.spring.boot.test"})
@EnableAutoConfiguration
public class ApplicationEntrance {
public static void main(String[] args) {
log.info("Meteor connector start");
new SpringApplicationBuilder()
.sources(ApplicationEntrance.class)
.web(WebApplicationType.SERVLET)
.run(args);
log.info("Meteor connector started");
}
}
以上信息皆可在此⽅方法进⾏行行配置,也可以使⽤用默认值。配置完成之后启动项⽬目,在浏览器器中输⼊入⽹网址
http://localhost:8080/swagger-ui.html,即可看到上⾯面的配置信息,效果如下
访问地址后,发现⻚页⾯面存在这样⼀一句句话: No operations defined in spec!,意思是没有找到相关的 API 内
容,这是因为还没有添加对应的 Controller 信息,接下来结合代码⼀一⼀一介绍各个注解的使⽤用
5.Swagger 常⽤用注解
Swagger 通过注解表明该接⼝口会⽣生成⽂文档,包括接⼝口名、请求⽅方法、参数、返回信息等,常⽤用注解内容如下:
作⽤用范围 | API | 使⽤用位置 |
---|---|---|
协议集描述 | @Api | ⽤用于 Controller 类上 |
协议描述 | @ApiOperation | ⽤在 Controller 的方法上 |
⾮对象参数集 | @ApiImplicitParams | ⽤在 Controller 的⽅法上 |
⾮对象参数描述 | @ApiImplicitParam | ⽤在 @ApiImplicitParams 的⽅法⾥边 |
响应集 | @ApiResponses | ⽤在 Controller 的⽅法上 |
响应信息参数 | @ApiResponse | 用在 @ApiResponses ⾥边 |
描述返回对象的意义 | @ApiModel | ⽤在返回对象类上 |
对象属性 | @ApiModelProperty | 用在出入参数对象的字段上 |
Api 作⽤用在 Controller 类上,做为 Swagger ⽂文档资源,该注解将⼀一个 Controller(Class)标注为⼀一个Swagger 资源(API)。在默认情况下, Swagger-Core 只会扫描解析具有 @Api 注解的类,⽽而会⾃自动忽略略其他类别资源(JAX-RS endpoints、 Servlets 等)的注解。
使⽤用示例例:
package com.spring.boot.test.controller;
import com.spring.boot.test.entity.Message;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* Description:
*
* @author lcc
* @version 1.0
* @date 2019/12/27 6:09 下午
*/
@Api(value = "消息", description = "消息操作 API", position = 100, protocols = "http")
@RestController
@RequestMapping("/")
public class MessageController {
@ApiOperation(
value = "消息列列表",
notes = "完整的消息内容列列表",
produces="application/json, application/xml",
consumes="application/json, application/xml",
response = List.class)
@GetMapping(value = "messages")
public List<Message> list() {
return null;
}
@ApiOperation(value = "添加消息", notes = "根据参数创建消息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "消息 ID", required = true, dataType = "Long", paramType = "query"),
@ApiImplicitParam(name = "text", value = "正⽂文", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "summary", value = "摘要", required = false, dataType = "String", paramType = "query"),
})
@PostMapping(value = "message")
public Message create(Message message) {
return null;
}
@ApiOperation(value = "修改消息", notes = "根据参数修改消息")
@PutMapping(value = "message")
@ApiResponses({
@ApiResponse(code = 100, message = "请求参数有误"),
@ApiResponse(code = 101, message = "未授权"),
@ApiResponse(code = 103, message = "禁⽌止访问"),
@ApiResponse(code = 104, message = "请求路路径不不存在"),
@ApiResponse(code = 200, message = "服务器器内部错误")
})
public Message modify(Message message) {
return null;
}
@ApiOperation(value = "删除消息", notes = "根据参数删除消息")
@DeleteMapping(value = "message")
@ApiResponses({
@ApiResponse(code = 100, message = "请求参数有误"),
@ApiResponse(code = 101, message = "未授权"),
@ApiResponse(code = 103, message = "禁⽌止访问"),
@ApiResponse(code = 104, message = "请求路路径不不存在"),
@ApiResponse(code = 200, message = "服务器器内部错误")
})
public Message delete(String id) {
return null;
}
@ApiModel(description = "响应对象")
public class BaseResult<T> {
private static final int SUCCESS_CODE = 0;
private static final String SUCCESS_MESSAGE = "成功";
@ApiModelProperty(value = "响应码", name = "code", required = true, example = " " + SUCCESS_CODE)
private int code;
@ApiModelProperty(value = "响应消息", name = "msg", required = true, example = SUCCESS_MESSAGE)
private String msg;
@ApiModelProperty(value = "响应数据", name = "data")
private T data;
}
}
与 Controller 注解并列列使⽤用,属性配置如表所示:
属性名称 | 备注 |
---|---|
value | url 的路径值 |
tags | 如果设置这个值, value 的值会被覆盖 |
description | 对 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 将在文档中隐藏 |
重启项目之后,在浏览器器中输⼊⽹网址 http://localhost:8080/swagger-ui.html#/message-controller,可以看到如下效果
⾃自动将 MessageController 内的⽅方法都添加了了映射,并标明了了每种⽅方法的请求⽅方式。
@ApiOperation 的使⽤用
ApiOperation 定义在⽅方法上,描述⽅方法名、⽅方法解释、返回信息、标记等信息。
属性名称 | 备注 |
---|---|
value | url 的路路径值 |
tags | |
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 | 扩展属性 |
@ApiImplicitParams 和 @ApiImplicitParam 的使⽤用
@ApiImplicitParams ⽤用于描述⽅方法的返回信息,和 @ApiImplicitParam 注解配合使⽤用; @ApiImplicitParam
⽤用来描述具体某⼀一个参数的信息,包括参数的名称、类型、限制等信息
name | 接收参数名 |
---|---|
value | 接收参数的意义描述 |
required | 参数是否必填值为 true 或者 false |
dataType | 参数的数据类型只作为标志说明,并没有实际验证 |
paramType | 查询参数类型,其值: path 以地址的形式提交数据 query 直接跟参数完成⾃自动映射赋 body 以流的形式提交,仅⽀支持 POST header 参数在 request headers ⾥里里边提交 form 以 form 表单的形式提交 仅⽀支持 POST |
defaultValue | 默认值 |
@ApiResponses 和 @ApiResponse 的使⽤用
@ApiResponses 主要封装⽅方法的返回信息和 @ApiResponse 配置起来使⽤用, @ApiResponse 定义返回的具
体信息包括返回码、返回信息等。
属性名称 | 备注 |
---|---|
code | http 的状态码 |
message | 描述 |
response | 默认响应类 Void |
reference | 参考 |
responseHeaders | 封装返回信息 |
responseContainer | 字符串串 |
@ApiModel 和 @ApiModelProperty 的使⽤用
在实际的项⽬目中我们常常会封装⼀一个对象作为返回值, @ApiModel 就是负责描述对象的信息,
@ApiModelProperty 负责描述对象中属性的相关内容。
属性名称 | 备注 |
---|---|
value | 属性描述 |
name | 如果配置覆盖属性名称 |
allowableValues | 允许的值 |
access | 可以不不配置 |
notes | 没有使⽤用 |
dataType | 数据类型 |
required | 是否为必传参数 |
position | 显示的顺序位置 |
hidden | 是否因此 |
example | 举例例 |
readOnly | 只读 |
reference | 引⽤用 |
7.Try it out
使⽤用 Swagger 创建的在线 API 还有⼀一个⾮非常强⼤大的功能,可以在⻚页⾯面直接测试接⼝口的可⽤用性,这样在前端
和后端接⼝口调试出现问题时,可以⾮非常⽅方便便地利利⽤用此功能进⾏行行接⼝口验证。在上⾯面参数讲解过程中,我们发现
每个接⼝口描述右侧都有⼀一个按钮 try it out,单击 try it out 按钮即可进⼊入表单⻚页⾯面,如下
在表单⻚页⾯面添加相关字段后,单击“Execute”按钮就会将请求发送到后台,从⽽而进⾏行行接⼝口验证,通过按钮下⾯面
的命令可以看出,实际上是使⽤用了了 curl 命令进⾏行行的 post 测试:
curl -X POST "http://localhost:8080/message?id=1&text=1&summary=1" -H "accept: */*"
在后端调整 Swagger ⽅方法上对应参数,即可看到 curl 命令参数的变化。
8.总结
通过这节课的学习我们掌握了了在 Spring Boot 项⽬目中使⽤用 Swagger,利利⽤用 Swagger 的相关注解可以容易易地构
建出丰富的 API ⽂文档。使⽤用 Swagger 之后可以帮助⽣生成标准的 API 说明⽂文档,避免接⼝口交互中的低效沟通
问题, Swagger 做为强⼤大的 API ⽣生成框架其实还有更更多的功能,⼤大家有机会可以在线下继续学习
推荐阅读
-
Spring boot :使用 Swagger 2 构建 RESTful APIs
-
Spring MVC利用Swagger2如何构建动态RESTful API详解
-
Spring boot 入门 2、springboot 使用 swagger2 编写接口文档
-
Spring Boot集成springfox-swagger2构建restful API的方法教程
-
Spring MVC集成springfox-swagger2构建restful API的方法详解
-
Spring Boot 项目中使用Swagger2的示例
-
Spring MVC集成springfox-swagger2构建restful API的方法详解
-
Spring Boot集成springfox-swagger2构建restful API的方法教程
-
Spring Boot 项目中使用Swagger2的示例
-
详解spring cloud整合Swagger2构建RESTful服务的APIs