Spring Boot之整合Swagger
前言
经过之前文章的学习,我们学会了:
- 5分钟入手Spring Boot;
-
Spring Boot项目中访问数据库;
1. Spring Boot数据库交互之Spring Data JPA;
2. Spring Boot数据库交互之Mybatis; - Spring Boot视图技术;
有了这些基础知识,可以说,我们已经拥有Spring Boot项目开发的入门基础了。
现实场景中,我们往往需要知道API的文档,才能用于测试、交付等,土一点的做法是开发人员编写API文档,如Wiki、Word、其他在线文档等,实际上,有很多开源资源帮我们从技术上实现了API规格的文档化,而Swagger是Spring Boot生态中的佼佼者,也是官方推荐的。
Swagger的主要优点有:
- 免费开源,并且官网提供了丰富的工具和文档介绍;
- 通过代码添加注解,自动生成API文档;
- 提供在线API文档,API文档随API变化而自动同步更新;
- 可开启UI界面,界面美观、清晰;
- UI界面支持在线测试API;
- 支持多种语言(Java,PHP...);
- 采用OpenAPI 规范;
(OpenAPI定义了RESTful APIs的编写规范。规范中指定了一套模式/模型。这套规范是Swagger为各种编程语言编写的服务提供接口文档奠定了基础。) - ...
那么,我们今天就一起来学习:
Spring Boot中通过Swagger来做API文档。
本文使用的项目代码,是基于上一篇文章使用的Spring Boot项目:
Spring Boot数据库交互之Mybatis
主要步骤
- 添加依赖;
- 创建config包;
- 创建配置类;
- 编写配置类;
- 修饰Controller;
- 修饰项目启动类;
- 启动项目、使用Swagger;
1.添加依赖;
//在pom.xml文件中的dependencies节点内添加以下内容:
<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>
2.创建config包;
项目根目录下创建config包:
配置类3.创建配置类;
4.编写配置类;
1. 编写Swagger配置类;
该步骤的意义:
配置Swagger要扫描API的Controller位置、要显示的API path的样式、初始化的Swagger页面的一些基础信息(见apiInfo()方法);
-
特别注意,要使用@EnableSwagger2注解;
-
设置生成API接口信息的被扫描Controller路径,常见写法:
//生成指定包下的所有API接口信息
RequestHandlerSelectors.basePackage("com.mycompany.sample.controller")
//生成所有API接口
RequestHandlerSelectors.any()
//所有API接口都不生成
RequestHandlerSelectors.none()
//只生成被@Api 这个注解注解过的类接口
RequestHandlerSelectors.withClassAnnotation(Api.class)
//只生成被@ApiOperation 这个注解注解过的API接口
RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)
-
设置API路径筛选规则,常见写法有:
//所有API均允许生成
PathSelectors.any()
//所有API均不允许生成
PathSelectors.none()
//正则表达式匹配,匹配上则允许生成,如包含getLead的API:
PathSelectors.regex("^(?!getLead).*$")
//只扫描指定的路径下的请求,如只想扫描getLead API路径下的:
//getLead为API path的一部分
PathSelectors.ant("/getLead/**")
代码如下:
package com.mycompany.sample.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;
/**
* @author : dylanz
* @since : 07/17/2020
**/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {//名字不限
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(true)
.select()
.apis(RequestHandlerSelectors.basePackage("com.mycompany.sample.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {//名字不限
Contact contact = new Contact("Dylan Zhang", "https://www.jianshu.com/u/56578a39a99a", "997604787@qq.com");
return new ApiInfoBuilder()
.title("Lead API")
.contact(contact)
.description("Lead related operations")
.termsOfServiceUrl("http://127.0.0.1:8080/getLead/10130546")
.version("1.0")
.build();
}
}
-
如果想关闭Swagger UI:
enable设置为:.enable(false),之后访问Swagger UI时就会如下:
关闭Swagger UI2. 编写WebMvcConfig配置类;
该步骤的意义:覆盖、重写项目配置的(如有)、默认的静态资源路径,这样才能读取到Swagger jar包内的静态文件(html、css文件等);
package com.mycompany.sample.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import javax.annotation.PostConstruct;
/**
* @author : dylanz
* @since : 07/17/2020
**/
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@PostConstruct
public void init() {
System.out.println("Init in WebMvcConfig...");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/statics/");
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
5.修饰Controller;
package com.mycompany.sample.controller;
import com.mycompany.sample.domain.Lead;
import com.mycompany.sample.service.LeadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author : dylanz
* @since : 07/07/2020
**/
@RestController
@Api
public class LeadController {
@Autowired
private LeadService leadService;
@GetMapping("/getLead/{leadId}")
@ResponseBody
@ApiOperation(value = "get lead by leadId", httpMethod = "GET")
@ApiImplicitParams(
{@ApiImplicitParam(name = "leadId", value = "leadId", required = true, paramType = "path", dataType = "Long", example = "10130546")}
)
public Lead getLead(@PathVariable(name = "leadId") Long leadId) {
return leadService.getLeadByLeadId(leadId);
}
}
1. @Api 注解用来描述该服务的信息,如果不使用则显示类名称;
2. @ApiOperation 注解用于描述接口信息;
3. @ApiParam,@ApiImplicitParam,@ApiImplicitParams 注解用于描述接口的参数;
4. @ApiResponse,@ApiResponses 注解用于描述API返回的信息,不使用会使用默认的、根据接口情况自动生成的描述信息,可在此处自定义错误返回信息,如:
@ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
5. @ApiVersion 注解用于描述接口的版本信息;
6.修饰项目启动类;
特别注意,只增加使用@EnableSwagger2注解即可;
package com.mycompany.sample;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author : dylanz
* @since : 07/07/2020
**/
@SpringBootApplication
@EnableSwagger2
@MapperScan(basePackages = "com.mycompany.sample.dao")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
7.启动项目、使用Swagger;
-
启动项目;
-
访问Swagger UI;
Swagger UI HTML站点:http://localhost:8080/swagger-ui.html
HTML站点页面组成:
1. 标题;
2. API文档JSON入口:http://localhost:8080/v2/api-docs;
3. 作者信息;
4. API文档主体;
5. 等。
打开折叠的API列表,我们能看到API的规格:
API规格以及API使用的实体对象信息:
实体对象信息我们还可以编辑实体类,修改、细化实体的展示:
package com.mycompany.sample.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author : dylanz
* @since : 07/07/2020
**/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@ApiModel
public class Lead implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "leadId", dataType = "Long", name = "id", example = "10130546")
private Long leadId;
@ApiModelProperty(value = "email", dataType = "String", name = "email", example = "dylan.zhang@xxxx.com")
private String email;
}
@ApiModel:生成swagger时扫描的实体注解;
@ApiModelProperty:属性注解,可用于描述实体属性;
修改后,效果如下:
实体注解还有我特别喜欢的测试API的功能
1. 点击API规格右上角的"Try it out"按钮:
Try it out2. 点击Execute按钮,测试API:
3. API测试返回:
API返回我们可以在页面上修改API参数,如本例为leadId,进行不同参数值的测试(Request Body也支持),而不需要其他测试工具或测试代码,相当方便;
(本例中,我们在controller内@ApiImplicitParam注解中设置了默认值:example = "10130546")
使用Swagger来管理API文档是十分方便、快捷的,界面美观、并且有测试API的功能,对开发人员、测试人员十分友好,满足了绝大多数API文档化的需求。
凡事也要从不同的角度来看待,Swagger强大的背后,也有其一定的局限性:
- 仅对于Restful API支持较为友好,其他类型的API支持得不是很好;
- 对代码有一定的侵入性;
- Swagger与代码需要强绑定;
(每个API都需要人为添加注解,如果有人偷懒,在API开发时没有加上Swagger对应的注解,那么Swagger UI上是看不到该API的) - ...
综合来看,我还是很喜欢Swagger的,使用简单,功能强大!!!
你Get到了吗?