目录
一、Swagger简介
二、spring boot集成Swagger
2.1 maven坐标
2.2 配置类(Springboot集成)
2.3 启动并访问
2.4 配置Swagger
2.4.1 Swagger的bean实例Docket
2.4.1.1源码解析DocumentationType.SWAGGER_2含义
2.4.1.2 源码解析Swagger 配置信息 Docket.ApiInfo
2.4.1.3 源码解析ApiInfo中的Contact参数
2.4.2 如何替换掉默认ApiInfo?
2.4.3 Swagger配置扫描接口 Docket.select
2.4.3.1 扫描指定的包
2.4.3.2 扫描全部的包
2.4.3.3 都不扫描
2.4.3.4 扫描类上的注解
2.4.3.5 扫描方法上的注解
2.4.3.6 过滤路径
2.4.4 配置是否启动Swagger
2.4.4.1 希望Swagger在生产环境中使用但发布时不适用
2.4.5 配置Api文档的分组
2.4.5.1 配置多个组
2.5 实体类配置
2.5.1 @ApiModel 与@ApiProperty
2.5.2 @ApiOperation
2.5.3 @ApiParam
注意点! 在正式发布的时候要关闭swagger(出于安全考虑,而且节省内存空间)
之前开发的时候,前端只用管理静态页面, http请求到后端, 模板引擎JSP,故后端是主力
如今是前后端分离时代:
后端:后端控制层,服务层,数据访问层
前端:前端控制层,视图层
伪造后端数据(JSON格式),便不再需要后端 ,方便了开发,等到前后端都开发完成之后,便不再使用伪造数据,而是访问远程后端接口
前后端如何交互? API文档
前后端相对独立,松耦合,甚至前后端可以部署在不同的服务器上(因为是调用接口,所以在哪个服务器上无所谓)
产生的问题:
前后端继承联调,前端人员和后端人员无法做到及时协商 ----一定要尽早沟通解决
解决方案:
指定计划提纲,实时更新API,降低集成风险
前后端分离之后,后端提供接口,需要实时更新最新的消息及改动
Swagger诞生!!!
官方网站: API Documentation & Design Tools for Teams | Swagger
官方文档: Annotations · swagger-api/swagger-core Wiki · GitHub
RestFul Api文档在线自动生成工具 =》Api文档与API定义同步更新
直接运行,可以在线测试API接口
支持多种语言
在项目使用Swagger需要springbox:
swagger2
ui
需要上面的两个组件,导入上面的两个坐标
第一步肯定是创建一个springboot项目,第二步导入maven坐标,万古不变的两步
如果运行程序的时候出现错误,或许可以将下面swagger-ui依赖和swagger2依赖的版本降低一些,比如说降低到2.7.0
io.springfox
springfox-swagger-ui
2.9.2
io.springfox
springfox-swagger2
2.9.2
org.springframework.boot
spring-boot-starter-web
2.3.7.RELEASE
如果适用2.7.0还会有错误,建议降低springboot版本号到2.5.0
org.springframework.boot
spring-boot-starter-parent
2.5.0
swagger-ui.html访问不到404,那就降低我们刚刚两个左边的版本,比如改成2.7.0(两个依赖都要改)
如果在启动时出现了其他的方法,也可以尝试将依赖的版本降低一些
@EnableSwagger2注解的作用是启用Swagger2自动生成API文档并提供可视化的界面,方便开发人员查看和测试API
下面的这段代码是使用的默认的swagger配置
@Configuration //加入到容器里面
@EnableSwagger2 //开启Swagger
public class SwaggerConfig {
}
Swagger UI
下面是效果图
Swagger的bean实例Docket
@Configuration //加入到容器里面
@EnableSwagger2 //开启Swagger
public class SwaggerConfig {
// 配置了Swagger的Docket实例
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2);
}
}
这个地方为什么传一个他呀?
我们看一下Docket构造器,发现传入DocumentationType类型的参数
我们查看一下DocumentationType类
我们再看一下这些字段,很明显我们是2.0版本,故传入DocumentationType.SWAGGER_2
另外插一句话
在我们还没有配置之前,我们可以先点进这个Docket类中看一下,有一个默认的分组
现在我们在swagger-ui页面上观看一下,具体是对应的哪一部分的信息
很明显是页面右上角的位置
在Docket类中找到下面这个构造方法,并且可以查看一下ApiInfo.DEFAULT,这个就是默认的
下面我们就来看一下这个的源码
在ApiInfo中,我们成功找到这个字段
将这个类往下翻翻,还会发现一个静态代码块:
我们发现静态代码块中的信息和swagger页面的信息是一个样子的,说明这个就是默认的配置,在类编译的时候就会加载(DEFAULT就是在这个地方被赋值的)
static {
DEFAULT = new ApiInfo("Api Documentation", "Api Documentation", "1.0", "urn:tos", DEFAULT_CONTACT, "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList());
}
上面的这些信息对下的就是swagger-ui页面的下图信息
我们在源码中发现
其中DEFAULT_CONTACT是作者信息,如下图所示,发现都是空的
下面我们将这个配置改一下,如下代码所示
@Configuration //加入到容器里面
@EnableSwagger2 //开启Swagger
public class SwaggerConfig {
// 配置了Swagger的Docket实例
@Bean
public Docket docket() {
// Docket有很多的配置,我们可以先配置一个apiInfo()
// apiInfo()里面需要传入一个ApiInfo的参数,那我们就在下面定义一个
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
// 配置Swagger信息 = apiInfo
private ApiInfo apiInfo(){
// 下面的这套配置就把原来的static代码块覆盖掉
// 作者信息,通过查看源码得知
Contact contact = new Contact("张靖奇", "https://blog.kuangstudy.com/", "[email protected]");
return new ApiInfo(
"张靖奇的API文档",
"练习!!!!!!!",
"v1.0",
"https://blog.kuangstudy.com/",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
之前的效果图:
如今的效果图:
假如说出不来下面的效果图,仍然是上面的效果图,给浏览器清理缓存再刷新即可
备注:这个框框圈出来的东西,至于文档名和描述信息有用,其他的没有用
我们再select()之后继续加点,我们发现只能再加上apis,paths
指定扫描com.example.controller包
@Bean
public Docket docket() {
// Docket有很多的配置,我们可以先配置一个apiInfo()
// apiInfo()里面需要传入一个ApiInfo的参数,那我们就在下面定义一个
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
// select()参数里面需要传入一个Docket,可以返回一个ApiSelectorBuilder
.select()
// RequestHandlerSelectors,配置要扫描接口的方式
// basePackage("com.example") 指定扫描这个包
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.build();
}
.apis(RequestHandlerSelectors.any())
.apis(RequestHandlerSelectors.none())
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
ant() 过滤路径的
表示在com.example.controller包下的路径为/kuang开头的所有请求
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.ant("/kuang/**"))
any()全部都过滤
none()全部都不过滤
regex()根据正则表达式过滤
查看Docket源码,发现有一个enabed
默认为true,表示启动Swagger
如果为false,则Swagger不能在浏览器中访问
我们也可以把这个值改成false
注意!! 这个点的时候,一定不要在build()后面点(从select到build是一套的)
此时重启之后访问不到页面
判断是不是生产环境 flag=false
注入enable(flag)
多配置是怎么来的?怎么确定是生产环境还是发布环境?
acceptsProfiles(Profiles profiles) 监听,返回boolean,其中Profiles是org.springframework.core.env
getDefaultProfiles() 获得默认的文件名,返回String[]
getActiveProfiles() 获得激活的文件名,返回String[]
如下代码所示,我们配置的是当在dev,test这两个版本下才能进入到swagger,重启刷新swagger-ui界面,他是直接访问不到的
@Bean
public Docket docket(Environment environment) {
// 获取项目的环境
// 这个地方是可变长参数,可以写好几个
Profiles profiles = Profiles.of("dev","test");
// 如果是dev、test,这个地方的返回值就是true
boolean flag = environment.acceptsProfiles(profiles);
// Docket有很多的配置,我们可以先配置一个apiInfo()
// apiInfo()里面需要传入一个ApiInfo的参数,那我们就在下面定义一个
return new Docket(DocumentationType.SWAGGER_2)
.enable(flag)
.apiInfo(apiInfo())
// select()参数里面需要传入一个Docket,可以返回一个ApiSelectorBuilder
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.build();
}
此时我们修改一下application.yaml文件,以及新增两个配置文件
application.yaml
#激活环境
spring:
profiles:
active: dev
application-dev.yaml
server:
port: 8081
application-pro.yaml
server:
port: 8082
修改及添加之后,再次访问页面,这次如果我们用8080端口是访问不到的,因为我们在application中配置的是dev环境,此时会直接向application-dev文件寻找,成为8081端口
配置多个Docket然后点就行
只要我们的接口中的返回值存在实体类,就会被扫描到Swagger(前提是Swagger会扫描到所在的包,一定看好范围)
@RestController
@RequestMapping("/test")
@Api(value = "测试一下")
public class TestController {
@GetMapping("/userinfo")
@ApiOperation("获取用户列表信息")
public User getUserInfo(){
User user = new User();
return user;
}
}
public class User {
public String user;
public String password;
}
效果如下图所示:
但是上边的都是英文,一般人会看不懂,但是我们可以加一些中文备注,这些中文备注就需要用到下面的注解
(31条消息) @ApiModel注解与@ApiModelProperty注解_我爱布朗熊的博客-CSDN博客
这个注解的作用就是给接口加了一个中文注释而已
@GetMapping("/userinfo")
@ApiOperation("获取用户列表信息")
public User getUserInfo(){
User user = new User("aaa","aaaaa");
return user;
}
@GetMapping("/hello2")
public String hello2(@ApiParam("用户名") String username){
return "hello";
}