Swagger整合SpringBoot

一Swagger简介

1. 前后端分离

后端时代:前端只用管理静态页面;html等静态资源交给后端通过模板引擎进行渲染

前后端分离时代

  • 后端:控制层controller、服务层service、数据访问层dao

  • 前端:前端控制层、视图层

  • 前后端交互:通过API接口

  • 前后端相对独立,松耦合,甚至可以部署在不同的服务器上

随之产生的问题:前后端联调,前端人员和后端人员无法做到及时协商,尽早解决

解决方案

  • 首先指定schema,实时更新最新的API,降低集成风险

  • 早些年:指定word计划文档

  • 前后端分离:

    • 前端测试后端接口数据是否正确:postman
    • 后端提供接口,需要实时更新最新的消息和改动

于是Swagger应运而生

2.Swagger引入

  • 号称历史上最流行的api框架
  • RestFul Api文档在线生成工具=》Api文档与Api定义同步更新
  • 直接运行,可以在线测试Api接口
  • 支持多种语言

官网:https://swagger.io/

在这里插入图片描述

二、SpringBoot集成Swagger

1. 导入Swagger依赖

springfox-swagger2

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

springfox-swagger-ui

<!-- 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>

2. 编写Swagger配置类

在主程序同级目录下新建config包,其中新建SwaggerConfig配置类

  • 记住用@Configuration注解注明这是配置类
  • 同时用@EnableSwagger2注解开启Swagger2
@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {

}

3.遇到一个错误

Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException

springboot 集成Swagger2报错

这里使用的Swagger版本是2.9.2、springboot 版本是2.6.4

发现是springboot版本太高,缺少swagger运行所需要的环境,具体缺少什么还没研究出来,所以只能回退到之前的版本

把springboot回退到2.5.6就能正常启动

4.测试进入Sawgger页面

重启主程序,访问localhost:8080/swagger-ui.html

在这里插入图片描述

这个界面是Swagger为我们提供的ui界面,我们可以在源码中找到它

在这里插入图片描述

5.配置Swagger API信息

在Swagger提供的ui界面,其中的Swagger信息模块我们可以自定义信息内容

我们只需要在Swagger配置类SwaggerConfig中实例化Docket类队对象的bean实例,通过配置ApiInfo类的信息然后传入Docket的bean实例即可

在这里插入图片描述

@Configuration
@EnableSwagger2      //开启Swagger2
public class SwaggerConfig {	
	//配置了Swagger的Docket的bean实例
	@Bean
	public Docket docket(Environment environment){
		return new Docket(DocumentationType.SWAGGER_2)
				.apiInfo(apiInfo());
	}
	
	//配置Swagger信息=apiInfo
	private ApiInfo apiInfo(){
		Contact contact = new Contact("艾孜", "https://blog.csdn.net/weixin_49133806?spm=1018.2226.3001.5343", "2271427740@qq.com");
		return new ApiInfo(
				"Aize.swaggerAPI文档",
				"我的API文档",
				"V1.0",
				"https://blog.csdn.net/weixin_49133806?spm=1018.2226.3001.5343",
				contact,
				"Apache 2.0",
				"https://www.apache.org/licenses/LICENSE-2.0",
				new ArrayList<>()
		);
	}
}

重启主程序测试,可以看到Swagger信息已经变更成我们定义的信息

在这里插入图片描述

6. 配置Swagger自定义扫描接口

我们在这个ui界面中,可以看到扫描了两个controller接口

在这里插入图片描述

一个是默认的/error请求,也就是我们启动springboot主程序未加配置默认访问8080端口的默认controller

另一个是我们自己写的/hello请求,对应着HelloController,由于我们用的@RequsetMapping注解,所以请求的方式有以上的六种

在这里插入图片描述

接下来我们自己配置以下要扫描的接口

@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())//配置Swagger信息
            .select()
            /**
             * apis():指定扫描的接口
             *  RequestHandlerSelectors:配置要扫描接口的方式
             *       basePackage:指定要扫描的包
             *       any:扫面全部
             *       none:不扫描
             *       withClassAnnotation:扫描类上的注解(参数是类上注解的class对象)
             *       withMethodAnnotation:扫描方法上的注解(参数是方法上的注解的class对象)
             */
            .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
            /**
             * paths():过滤路径
             *  PathSelectors:配置过滤的路径
             *      any:过滤全部路径
             *      none:不过滤路径
             *      ant:过滤指定路径:按照按照Spring的AntPathMatcher提供的match方法进行匹配
             *      regex:过滤指定路径:按照String的matches方法进行匹配
             */
            .paths(PathSelectors.ant("/example/**"))
            .build();
}

其中.select().apis.paths.build是一套组合进行使用

然后我们启动主程序访问localhost:8080/swagger-ui.html进行测试

在这里插入图片描述

可以发现No opertations defined in spec,这是因为我们过滤了/example下的所有controller

我们将过滤条件更改为过滤全部路径

.paths(PathSelectors.any())

7. 配置是否启动Swagger

我么通过Docket对象的.enable方法来配置swagger是否启动

@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())//配置Swagger信息
            .enable(false)//配置是否启动swagger,默认为true
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
            .paths(PathSelectors.ant("/example/**"))
            .build();
}

更改为false后启动测试一下,查看控制台,无法进入到swagger页面

在这里插入图片描述

如果我们有这样一个需求:希望Swagger在开发环境中,在正式环境时不能使用

  • 首先要判断是不是开发环境,可以设置一个flag表示用来表示:flag=1即表示生产环境
  • 然后将flag的值传给enable(flag)

首先在resources目录下新建两种springboot配置文件:

  • 开发环境:application-dev.properties

    server.port=8081
    
  • 正式环境:application-pro.properties

    server.port=8082
    
    

然后在主配置文件application.properties中激活开发环境

spring.profiles.active=dev

在这里插入图片描述

然后我们到SwaggerConfig中的docket()方法中添加代码:

  • 首先给该方法传一个参数Environment的实例

    Environment environment
    
  • 首先设置药配置的Swagger环境:这里可以添加多个环境

    Profiles profiles = Profiles.of("dev", "test");
    
  • 然后通过environment.acceptsProfiles方法判断是否处在上一步设定的dev/test环境中,返回一个boolean的值,我们用flag接收

    boolean flag = environment.acceptsProfiles(profiles);
    
  • 然后修改enable中的参数为flag,即通过flag来判断是否开启Swagger

    .enable(flag)//通过flag判断是否开启
    

完整代码:

@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {
    //配置Swagger的Docket的bean实例
    @Bean
    public Docket docket(Environment environment) {
        //设置要配置的Swagger环境
        Profiles profiles = Profiles.of("dev", "test");
        //通过environment.acceptsProfiles判断是否处在自己设定的环境中
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())//配置Swagger信息
                .enable(flag)//通过flag判断是否开启
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
                .paths(PathSelectors.ant("/example/**"))
                .build();
    }

	//配置Swagger信息=apiInfo
	private ApiInfo apiInfo(){
		Contact contact = new Contact("艾孜", "https://blog.csdn.net/weixin_49133806?spm=1018.2226.3001.5343", "2271427740@qq.com");
		return new ApiInfo(
				"Aize.swaggerAPI文档",
				"我的API文档",
				"V1.0",
				"https://blog.csdn.net/weixin_49133806?spm=1018.2226.3001.5343",
				contact,
				"Apache 2.0",
				"https://www.apache.org/licenses/LICENSE-2.0",
				new ArrayList<>()
		);
	}
}

然后启动主程序测试:由于激活了dev开发环境,所以访问localhost:8081/swagger-ui.html

成功开启swagger,如果我们修改主配置文件,激活pro正式发布环境

spring.profiles.active=pro

8. 配置API文档分组

我们可以在docket通过.groupName中设置组名

public Docket docket(Environment environment) {
    //设置要配置的Swagger环境
    Profiles profiles = Profiles.of("dev", "test");
    //通过environment.acceptsProfiles判断是否处在自己设定的环境中
    boolean flag = environment.acceptsProfiles(profiles);

    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())//配置Swagger信息
            .groupName("azmat")
            .enable(true)//配置是否启动swagger,默认为true
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
            .paths(PathSelectors.any())
            .build();
}
1. 配置多个组

上述我们成功修改了组名,但是只有一个组,如果我们想要多个组呢?

观察代码可以知道,一个Docket实例就对应着一个组,因此我们配置多个docket就对应着多个组

我们新增两个Docket的bean实例

@Bean
public Docket docket1() {
   return new Docket(DocumentationType.SWAGGER_2).groupName("A");
}
@Bean
public Docket docket2() {
   return new Docket(DocumentationType.SWAGGER_2).groupName("B");
}

再次重启测试,就可以看到多个组并选择

在这里插入图片描述

9. 配置Model实体类

1.新建实体类

在主程序同级目录下新建pojo包,其中新建User实体类

public class User {
    public String username;
    public String password;
}
2. 编写对应请求接口
@GetMapping("/getUser")
public User getUser() {
    return new User();
}
3. 常用注解

我们可以在实体类上和其属性上添加注解来添加对应的注释

  • @ApiModel为类添加注释
  • @ApiModelProperty为类属性添加注释
@ApiModel("用户实体类")
public class User {
   
   @ApiModelProperty("用户名")
   public String username;
   @ApiModelProperty("用户密码")
   public String password;
}

重启测试,即可以看到注释信息

在这里插入图片描述

我们同样可以在Controller类和其中的方法上添加相应的注解

@Api(tags = "Hello控制类")
@RestController
public class HelloController {
   
   @RequestMapping("/hello")
   public String hello(@ApiParam("用户名") String username) {
      return "hello" + username;
   }
   
   //只要我们的接口中,返回值中存在实体类,他就会被扫描到Swagger中
   @ApiOperation("Hello方法")
   @GetMapping("/getUser")
   public User user() {
      return new User();
   }
}

重启即可看到对应的注解

在这里插入图片描述

10. 测试Swagger的使用

1. 测试传参

我们在HelloController中新增一个方法,参数为username,可以用@ApiParam给该参数添加注解

@GetMapping("/username")
public String getUserName(@ApiParam("用户名") String username) {
    return username;
}

重启测试,可以看到我们添加的注释

在这里插入图片描述

我们可以简单测试一下,点击Try it out;然后以json的格式输入用户名,然后点击Execute执行

在这里插入图片描述

可以看到报错了,这是因为我们是使用的是Get方式:是通过URL的方式传递的,而不是通过请求体单独传参

在这里插入图片描述

我们将代码修改一下,将GetMapping改为PostMapping

@PostMapping("/username")
public String getUserName(@ApiParam("用户名") String username) {
   return username;
}

在这里插入图片描述

再次以json的格式输入参数username,可以看到成功了

在这里插入图片描述

2. 测试错误

我们在HelloController中新增一个方法,参数为User,可以用@ApiParam给该参数添加注解

@PostMapping("/getUser")
public User getUser(@ApiParam("用户名") User User) {
   return User;
}

找到对应的controller,点击Try it out测试,输入用户名和密码然后点击Excute

在这里插入图片描述

可以看到我们请求的URL完全正确,但是Response body相应体中用户名和密码都为空,这是因为我们的实体类没有添加对应的GET和SET方法,我们添加上去

@ApiModel("用户实体类")
public class User {
   
   @ApiModelProperty("用户名")
   public String username;
   @ApiModelProperty("用户密码")
   public 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;
   }
}

再次启动测试,成功!

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值