Swagger

小德 2021-12-02 12:57:59
Categories: Tags:

Swagger

1 什么是swagger

1
2
3
4
5
6
7
8
9
10
11
12
13
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。


总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

通俗的来讲,Swagger 就是将项目中所有(想要暴露的)接口展现在页面上,并且可以进行接口调用和测试的服务。

作用:
1. 接口的文档在线自动生成。
2. 功能测试。

https://swagger.io/

2 swagger的使用步骤

1
2
3
4
5
6
Swagger的使用分为以下 4 步:

1 添加依赖
2 开启 Swagger 功能
3 配置 Swagger 文档摘要信息
4 调用接口访问

3 使用

3.1 新建springboot项目

3.2 导入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
springfox

为什么是“springfox”?

问:我们要使用的是 Swagger,为什么要搜索“springfox”?

答:Swagger 可以看作是一个遵循了 OpenAPI 规范的一项技术,而 springfox 则是这项技术的具体实现。 就好比 Spring 中的 AOP 和 DI 一样,前者是思想,而后者是实现。



<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>

3.3 开启依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@EnableSwagger2
@SpringBootApplication
public class MyswApplication {

在主类上


访问即可。

http://localhost:8080/swagger-ui.html


basic-error-controller
Basic Error Controller
是springboot 自带的。

3.4 配置API文档信息

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
1 可以写一个配置类,转换到 配置类上,专门配置文档信息

@EnableSwagger2
@Configuration
public class SwaggerConfig {
@Bean
public Docket docket(){
// 配置API的文档信息
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}

/**
* this.title = title; 标题
* this.description = description; 描述
* this.version = version; 版本
* this.termsOfServiceUrl = termsOfServiceUrl; 公司url
* this.contact = contact; 类 要建
* this.license = license; 许可
* this.licenseUrl = licenseUrl; 许可
* this.vendorExtensions = Lists.newArrayList(vendorExtensions);
* @return

接口文档的信息
*/
public ApiInfo apiInfo(){
Contact xmx = new Contact("xmx", "www.xmx.com", "12@qq.com");
// 查看实现
return new ApiInfo("swagger学习","学习swagger",
"v1.0","www.xmx.com",
xmx,"","",new ArrayList<>()
);
}
}

下面如果配置自己类的扫描信息,还是可以用自己的配置。
@Bean
public Docket docket(){
// 配置API的文档信息
return new Docket(DocumentationType.SWAGGER_2)
.select().apis(RequestHandlerSelectors.any()).build().apiInfo(apiInfo()); // 默认配置
}

看了下面再看这里。

对比:

sw1

3.4.1 配置自己类的扫描信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@EnableSwagger2
@Configuration
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
// 配置扫描接口
// .select().apis(RequestHandlerSelectors.any()).build(); 默认配置
// .select().apis(RequestHandlerSelectors.none()).build(); //没有接口
// .select().apis(RequestHandlerSelectors.basePackage("com.xmx.controller")).build(); // 配置自己的扫描包
// .select().apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)).build(); //通过注解名称
.select().apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class)).build();// 通过方法的注解
}
}

如果上面的有多个选项,可以连着写 .apis()

1
2
3
4
5
6
7
8
9
10
11
12
13

@Bean
public Docket docket(){
// 配置API的文档信息
return new Docket(DocumentationType.SWAGGER_2)
//.select().apis(RequestHandlerSelectors.any()).build(); // 默认配置
//.select().apis(RequestHandlerSelectors.none()).build(); //没有接口
// .select().apis(RequestHandlerSelectors.basePackage("com.xmx.controller")).build(); // 配置自己的扫描包
.select().apis(RequestHandlerSelectors.withClassAnnotation(Controller.class))
.apis(RequestHandlerSelectors.basePackage("com.xmx.controller"))
.build(); //通过注解名称
}

3.4.2 某些包下特定的接口

1
2
3
4
5
6
7
8
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.xmx.controller"))
.paths(PathSelectors.ant("/emp/**")) // 只要hello 这种路径请求
.build();
}

3.4.3 配置忽略的请求参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    @Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.ignoredParameterTypes(Integer.class); // 忽略一种

}

@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.ignoredParameterTypes(Integer.class,String.class); // 忽略两种

}

@GetMapping("/hello/aa")
public String hello(Integer id,String name){
return "Hello World";
}

这种的用法在 ,比如请求对象中传入了 HttpSession HttpServletRequest等对象时,忽略。

3.5 是否能访问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
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Autowired
Environment environment;
@Bean
public Docket docket(){ // 描述文档信息
// 指定哪些环境通过
Profiles profiles=Profiles.of("dev","test");
// 判断是否是 dev test
boolean b= environment.acceptsProfiles(profiles);
// 配置API的文档信息
return new Docket(DocumentationType.SWAGGER_2)
.ignoredParameterTypes(Model.class,HttpSession.class) // 忽略某种参数
.enable(b); // enable 是否能访问接口文档
}
}
-- 通过指定不同的环境切换
spring.profiles.active=test

-- 也可以用 yml 多环境切换来测试

spring:
profiles:
active: sc

sw2

3.6 配置API分组

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
分组就是把API 划分为 不同的组,通过右上方的选择来操作。


@EnableSwagger2
@Configuration
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Hello模块")
.select()
.paths(PathSelectors.ant("/hello/**"))
.build();
}

@Bean
public Docket docketUser(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用户模块")
.select()
.paths(PathSelectors.ant("/user/**"))
.build();
}
}

3.7 实体配置

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
1 先删除所有的 配置,变成默认的。


2 测试的时候看,作为返回值 是 有 实体,还是 作为 传入值 有实体

@RestController
public class UserController {
@GetMapping("/user")
public String findUser(){
return "User helo";
}
@PostMapping("/user")
public String addUser(User user){
return "添加成功";
}
@GetMapping("/findById")
public User findById(Integer id){
return new User(1,"张三");
}
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer uid;
private String username;

}

前端不知道返回值是什么意思时,可以加注解:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("User实体")
public class User {
@ApiModelProperty("用户ID")
private Integer uid;
@ApiModelProperty("用户姓名")
private String username;

}

要在 Model中 有: 要么在 返回值值有,要么用传入参数的 JSON

@PutMapping("/addBook")
public String addBook(@RequestBody Book book){
return "OK";
}

image-20210720232458645

image-20210720233029559

3.8 开发中常用配置

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
1 清空.

2 一般扫描 controller包
@EnableSwagger2
@Configuration
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
// 配置扫描接口
.select().apis(RequestHandlerSelectors.basePackage("com.xmx.controller")).build(); // 配置自己的扫描包

}
}


3 正常的配置
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "图书相关请求")
@RestController
public class BookController {
@GetMapping("/getHello")
@ApiOperation("获取Book")
@ApiImplicitParams({
@ApiImplicitParam(name = "name",value = "图书名",dataType = "String",defaultValue = "平凡",example = "平凡的世界"),
@ApiImplicitParam(name="price",value="价格")
})
public String getHello(String name,Double price){
return "getHello";
}
}


3.9 问题解决

image-20210721001335445

1
2
3
4
5
6
7
8
9
打断点找:

@ApiModel("User实体")
public class User {
@ApiModelProperty(value="用户ID",example = "1")
private Integer uid;
@ApiModelProperty("用户姓名")
private String username;
}

image-20210910112302600