什么是Swagger2
当下很多公司都采取前后端分离的开发模式,前端和后端的工作由不同的工程师完成。在这种开发模式下,维持一份及时更新且完整的 API 文档将会极大的提高我们的工作效率。传统意义上的文档都是后端开发人员手动编写的,相信大家也都知道这种方式很难保证文档的及时性,这种文档久而久之也就会失去其参考意义,反而还会加大我们的沟通成本。而 Swagger 给我们提供了一个全新的维护 API 文档的方式,下面我们就来了解一下它的优点:
-
**代码变,文档变。**只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了 文档的时效性。 -
跨语言性,支持 40 多种语言。 -
Swagger UI 呈现出来的是一份可交互式的 API 文档,我们可以直接在文档页面尝试 API 的调用, 省去了准备复杂的调用参数的过程。 -
还可以将文档规范导入相关的工具(例如 Postman、SoapUI), 这些工具将会为我们自动地创建自 动化测试。
Swagger3
SpringBoot集成Swagger2
环境
jdk 1.8
SpringBoot 2.3.2
Swagger 2.9.2
步骤
1.在pom.xml加入swagger2相关依赖
<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.新建Swagger2Config配置类
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(adminApiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
private ApiInfo adminApiInfo(){
return new ApiInfoBuilder()
.title("Swagger2UI演示")
.description("此处为描述")
.version("1.0")
.build();
}
}
3.新建Controller和值对象
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/user")
public class DemoController {
@ApiOperation("登录")
@PostMapping("/login")
public String login(@RequestBody LoginRequest user) {
if (ObjectUtils.isEmpty(user.getUsername()) ||
ObjectUtils.isEmpty(user.getPassword())) {
return "用户名或密码错误";
}
if ("swagger2".equals(user.getUsername())) {
if ("123".equals(user.getPassword())) {
return "登录成功";
} else {
return "用户名或密码错误";
}
} else {
return "用户名或密码错误";
}
}
}
@ApiModel
public class LoginRequest {
@ApiModelProperty
private String username;
@ApiModelProperty
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4.访问测试 :http://localhost:8080/swagger-ui.html ,可以看到swagger的界面
配置扫描接口
- 构建Docket时通过select()方法配置扫描接口。
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(adminApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.goldwind.swagger_demo.controller"))
.paths(PathSelectors.any())
.build();
}
-
重启项目测试,由于我们配置根据包的路径扫描接口,所以我们只能看到一个类 -
除了通过包路径配置扫描接口外,还可以通过配置其他方式扫描接口,这里注释一下所有的配置方式:
any()
none()
withMethodAnnotation(final Class<? extends Annotation> annotation)
withClassAnnotation(final Class<? extends Annotation> annotation)
basePackage(final String basePackage)
- 除此之外,我们还可以配置接口扫描过滤:
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(adminApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.goldwind.swagger_demo.controller"))
.paths(PathSelectors.ant("/swagger_demo/**"))
.build();
}
- 这里的可选值还有
any()
none()
regex(final String pathRegex)
ant(final String antPattern)
配置Swagger开关
Swagger2目前有一些接口BUG,而且为了不暴露接口,所以生产环境的时候请务必关闭Swagger2的访问
方式一:
-
通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了 @Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(adminApiInfo())
.enable(false)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.paths(PathSelectors.ant("/swagger_demo/**"))
.build();
}
-
动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示 @Bean
public Docket docket(Environment environment) {
Profiles of = Profiles.of("dev", "test");
boolean b = environment.acceptsProfiles(of);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(adminApiInfo())
.enable(b)
.select()
.apis(RequestHandlerSelectors.basePackage("com.goldwind.swagger_demo.controller"))
.paths(PathSelectors.ant("/swagger_demo/**"))
.build();
}
方式二(推荐):
基于Profile 进行配置。我们知道@Profile 可以指定组件在哪个环境的情况下才能被注册到容器中。默认不指定,任何环境下都能注册这个组件。
我们可以通过``@Profile`注解来决定是否在指定的环境中进行注入。
@Configuration
@EnableSwagger2
@Profile({"dev","test"})
public class SwaggerConfig {
}
==优点:==利用Spring Boot的特性,根本不用去初始化组件,更加省事和安全
配置分组
-
通过groupName()方法配置分组 @Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.groupName("业务模块")
}
-
配置多个分组 @Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("业务模块");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("工具模块");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("管理模块");
}
实体类配置
- 实体类
@ApiModel("用户登录对象")
public class LoginRequest {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}
- 只要这个实体在请求接口的返回值上(即使是泛型),都能映射到实体项中:
@ApiOperation("获取用户")
@PostMapping("/get_user")
public User getUser(){
return new User();
- 重启查看
常用注解
Swagger的所有注解定义在io.swagger.annotations 包下
下面列一些经常用到的,未列举出来的可以另行查阅说明:
1.@Api()
用在请求的类上,表示对类的说明
@Api(tags = "测试用例1")
@Controller
public class swaggerTestUse(){
}
2.@ApiOperation()
用在请求的方法上,说明方法的作用
@Api("测试用例1")
@Controller
public class swaggerTestUse(){
@ApiOperation(value = "apiOperationSwaggerTest", notes = "apiOperationSwagger测试")
public void apiOperationSwaggerTest(){
}
}
3.@ApiParam()
作用于变量,说明变量的作用
@Api("测试用例1")
@Controller
public class swaggerTestUse(){
@ApiOperation(value = "apiOperationSwaggerTest", notes = "apiOperationSwagger测试")
public void apiOperationSwaggerTest(@ApiParam(name = "id", value = "id入参",
required = true) Integer id){
}
}
4.@ApiModel()
用在实体类上,描述实体类的含义
@ApiModel(description = "测试实体类", value = "测试实体类")
public class LoginRequest {
···
}
5.@ApiModelProperty()
用在属性上,描述响应类的属性
@ApiModel(description = "测试实体类", value = "测试实体类")
public class LoginRequest {
@ApiModelProperty(name = "userName", value = "用户名", required = false, exmaple = "小明")
private String userName;
}
6.@ApiImplicitParams()和@ApiImplicitParam()
用在请求的方法上,表示一组参数说明
@Api("测试用例1")
@Controller
public class swaggerTestUse(){
@ApiOperation(value = "apiOperationSwaggerTest", notes = "apiOperationSwagger测试")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "id入参", required = true, dataType = "Integer", paramType = "query"),
@ApiImplicitParam(name = "brand", value = "brand", required = true, dataType = "Brand", paramType = "body")
})
public void apiOperationSwaggerTest(Integer id, Brand band){
}
}
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
? name:参数名
? value:参数的汉字说明、解释
required:参数是否必须传
? paramType:参数放在哪个地方
? · header --> 请求参数的获取:@RequestHeader
? · query --> 请求参数的获取:@RequestParam
? · path(用于restful接口)--> 请求参数的获取:@PathVariable
? · body(不常用)
? · form(不常用)
? dataType:参数类型,默认String,其它值dataType="Integer"
? defaultValue:参数的默认值
请求头
在实际业务中,会遇到需要前端在请求头中往后端传递Token或者其他参数的需求。这里就需要进行如下的设置
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(adminApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.goldwind.swagger_demo.controller"))
.paths(PathSelectors.any())
.build()
.globalOperationParameters(operParameters());
}
private List<Parameter> operParameters(){
List<Parameter> operParameters = new ArrayList<>();
operParameters.add(new ParameterBuilder().name(HttpHeaders.ACCEPT_LANGUAGE)
.description("国际化语言(en-US-英语;zh-CN-中文)")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build());
operParameters.add(new ParameterBuilder()
.name(HttpHeaders.AUTHORIZATION)
.description("认证token")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build());
return operParameters;
}
全局配置
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(adminApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.goldwind.swagger_demo.controller"))
.paths(PathSelectors.any())
.build()
.securitySchemes(Lists.newArrayList(apiKey()));
}
private ApiKey apiKey() {
return new ApiKey(HttpHeaders.ACCEPT_LANGUAGE , HttpHeaders.ACCEPT_LANGUAGE, "header");
}
主题
Swagger2支持不同的主题页面
- 默认
http://localhost:8080/swagger-ui.html
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
- knife4j
http://localhost:8080/doc.html
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
<version>3.0.3</version>
</dependency>
优点:
-
支持标签页 -
自定义请求头 -
导出文档 -
请求参数缓存 -
动态参数 -
…
快速开始:https://doc.xiaominfo.com/knife4j/ 参考官方文档 😀
|