Swagger的使用

本文详细介绍了如何在SpringBoot项目中集成Swagger,包括配置步骤、自定义API文档信息和控制Swagger的开关,以提升前后端开发效率。
摘要由CSDN通过智能技术生成

Swagger

image-20230802151913510

学习目标
  • 了解Swagger的概念及作用
  • 掌握在项目中集成Swagger自动生成API文档

1、Swagger简介

前后端分离

  • 前端 -> 前端控制层、视图层
  • 后端 -> 后端控制层、服务层、数据访问层
  • 前后端通过API进行交互
  • 前后端相对独立且松耦合

产生的问题

  • 前后端集成,前端或者后端无法做到“及时协商,尽早解决”,最终导致问题集中爆发

解决方案

  • 首先定义schema [ 计划的提纲 ],并实时跟踪最新的API,降低集成风险

Swagger

  • 号称世界上最流行的API框架
  • Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新
  • 直接运行,在线测试API
  • 支持多种语言 (如:Java,PHP等)
  • 官网:https://swagger.io/

2、SpringBoot集成Swagger

SpringBoot集成Swagger => springfox,两个jar包

  • Springfox-swagger2
  • swagger-springmvc

使用Swagger

要求:jdk 1.8 + 否则swagger2无法运行

步骤:

1、新建一个SpringBoot-web项目

2、添加Maven依赖

<!-- 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、编写HelloController,测试确保运行成功!

4、要使用Swagger,我们需要编写一个配置类-SwaggerConfig来配置 Swagger

@Configuration //配置类
@EnableSwagger2// 开启Swagger2的自动配置
@EnableWebMvc//SpringBoot和swagger版本不匹配出现空指针异常,使用该注解解决
public class SwaggerConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        /** 配置knife4j 显示文档 */
        registry.addResourceHandler("doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        /**
         * 配置swagger-ui显示文档
         */
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        /** 公共部分内容 */
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

5、访问测试 :http://localhost:8080/swagger-ui.html ,可以看到swagger的界面;

image-20230802152518689

6、可以看到swagger官网有几大模块内容

  • 基本信息
  • 接口信息
  • 实体类信息

在这里插入图片描述

2.1 配置基本信息

Swagger 有自己的实例 Docket,如果我们想要自定义基本信息,可以使用 docket 来配置 swagger 的基本信息,基本信息的设置在 ApiInfo 这个对象中。

Swagger 默认的基本信息展示:

在这里插入图片描述

ApiInfo 中默认的基本设置

  • title:Api Documentation
  • description:Api Documentation
  • version:1.0
  • termsOfServiceUrl:urn:tos
  • contact:无
  • license:Apache 2.0
  • licenseUrl:http://www.apache.org/licenses/LICENSE-2.0

SwaggerConfig.java 配置文件添加以下内容:

//配置docket以配置Swagger具体参数
    @Bean
    public Docket docket() {
        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)
                // 配置基本信息
                .apiInfo(apiInfo())
                ;
    }

    //配置文档信息
    private ApiInfo apiInfo() {
        Contact contact = new Contact("韦杰豪", //作者名称
                "https://blog.csdn.net/weixin_49023961?type=blog", //作者网址
                "2827673986@qq.com"); //作者邮箱
        return new ApiInfoBuilder()
                .title("韦杰豪Swagger接口API") // 标题
                .description("众里寻他千百度,慕然回首那人却在灯火阑珊处") // 描述
                .termsOfServiceUrl("https://www.baidu.com") // 跳转连接
                .version("1.0") // 版本
                .license("Swagger-的使用(详细教程)")
                .licenseUrl("https://blog.csdn.net/weixin_49023961?type=blog")
                .contact(contact)
                .build();
    }

重启服务,打开 Swagger 文档,基本信息改变如下所示:

image-20230802155923374

2.2 配置接口信息

默认情况下,Swagger 是会展示所有的接口信息的,包括最基础的 basic-error 相关的接口

在这里插入图片描述

有时候我们希望不要展示 basic-error-controller 相关的接口,或者是说这想要显示某些接口,比如说com.itheima.controller 下的接口,由该怎么去实现呢?这个时候就需要设置 扫描接口

    @Bean
    public Docket docket() {
        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)

                // 配置接口信息
                .select() // 设置扫描接口
                // 配置如何扫描接口
                .apis(RequestHandlerSelectors
                        //.any() // 扫描全部的接口,默认
                        //.none() // 全部不扫描
                        .basePackage("com.itheima.controller") // 扫描指定包下的接口,最为常用
                        //.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口
                        //.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口

                )
            	//paths:过滤接口
                .paths(PathSelectors
                        .any() // 满足条件的路径,该断言总为true
                        //.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)
                        //.ant("/user/**") // 满足字符串表达式路径
                        //.regex("") // 符合正则的路径
                )
                .build();
    }

可根据自己的需求去设置对应的配置,这里我就不再一一赘述了,以上是我所设置的配置,重启服务,打开 Swagger 文档,接口信息改变如下所示:

image-20230802215708803

2.3 配置分组信息

Swagger 默认只有一个 default 分组选项,如果没有设置,所有的接口都会显示在default分组下,如果功能模块和接口数量一多,就会显得比较凌乱,不方便查找和使用。

swagger 文档中组名默认是 default,可通过 .groupName(String )

image-20230802220012984

//配置docket以配置Swagger具体参数
    @Bean
    public Docket docket() {
        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("韦杰豪")
                // 配置基本信息
                .apiInfo(apiInfo())
                .select() // 设置扫描接口
                // 配置如何扫描接口
                .apis(RequestHandlerSelectors
                   //.any() // 扫描全部的接口,默认
                   //.none() // 全部不扫描
                   .basePackage("com.itheima.controller") // 扫描指定包下的接口,最为常用
                   //.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口
                   //.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口
                    )
                .paths(PathSelectors
                       .any() // 满足条件的路径,该断言总为true
                        // .none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)
                        // .ant("/user/**") // 满足字符串表达式路径
                        //.regex("") // 符合正则的路径
                )
                .build();

    }

image-20230802220127089

如果需要配置多个组的话,就需要配置多个 docket() 方法,这里我就简单写两组,代码如下:

    /**
     * 展示 controller 包下所有的接口
     */
    @Bean
    public Docket docket1() {
        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("mike") // 修改组名为 "mike"
                // 配置接口信息
                .select() // 设置扫描接口
                // 配置如何扫描接口
                .apis(RequestHandlerSelectors
                        .basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用
                )
                .paths(PathSelectors
                         .any() // 满足条件的路径,该断言总为true
                )
                .build();
    }

    /**
     * 展示路径为 /error 的所有接口(基础接口)
     */
    @Bean
    public Docket docket2() {
        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("yank") // 修改组名为 "yank"
                // 配置接口信息
                .select() // 设置扫描接口
                // 配置如何扫描接口
                .apis(RequestHandlerSelectors
                        .any() // 扫描全部的接口,默认
                )
                .paths(PathSelectors
                        .ant("/error") // 满足字符串表达式路径
                )
                .build();
    }

重启服务,打开 Swagger 文档,接口信息改变如下所示:

组名为 mike 的文档中只有 user-controller 相关的接口信息

在这里插入图片描述

组名为 yank 的文档中只有 basic-error-controller 相关的接口信息

在这里插入图片描述

组名为 mike 的文档

在这里插入图片描述

2.4 控制Swagger的开关

在开发或者测试环境下,我们开启 swagger 会方便前端和后端的交互,但是如果在生产环境下也开启 swagger 的话,是会将接口暴露出去的,有极大风险,如何让 swagger 根据不同的环境来决定是否开启?

这里我准备了四个项目的配置文件,devtestpro 三个环境的配置文件仅是端口上的不同

在这里插入图片描述

  • application.yml -------------------------- 全局配置文件
  • application-dev.yml -------------------- 开发环境配置文件
  • application-test.yml -------------------- 测试环境配置文件
  • application-pro.yml -------------------- 生产环境配置文件

application.yml 内容如下,用于指定选择的环境:

spring:
  profiles:
    active: dev

可以通过代码判断此时是在什么环境:devtestpro,如果是在 pro 生产环境,则关闭 swagger。

    /**
     * swagger 配置
     * @param environment 环境
     */
    @Bean
    public Docket docket(Environment environment) {

        // 设置环境范围
        Profiles profiles = Profiles.of("dev","test");
        // 如果在该环境返回内则返回:true,反之返回 false
        boolean flag = environment.acceptsProfiles(profiles);

        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(flag) // 是否开启 swagger:true -> 开启,false -> 关闭
                ;
    }

application.yml 全局配置文件中环境指向 dev 时,是可以打开 swagger 的

在这里插入图片描述

如果我将 application.yml 全局配置文件中环境指向 pro 时,就不能打开 swagger 了,提示 Could not render e, see the console

在这里插入图片描述

拓展

通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了

@Bean
public Docket docket() {
   return new Docket(DocumentationType.SWAGGER_2)
      .apiInfo(apiInfo())
      .enable(false) //配置是否启用Swagger,如果是false,在浏览器将无法访问
      .select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
      .apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
       // 配置如何通过path过滤,即这里只扫描请求以/kuang开头的接口
      .paths(PathSelectors.ant("/kuang/**"))
      .build();
}

图片

2.5 实体类的配置

1、新建一个实体类

@ApiModel("图书实体")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
        @ApiModelProperty("图书ID")
        private Integer id;
        @ApiModelProperty("图书类型")
        private String type;
        @ApiModelProperty("图书名称")
        private String name;
        @ApiModelProperty("图书描述信息")
        private String description;

}

2、只要这个实体在请求接口的返回值上(即使是泛型),都能映射到实体项中:

@RequestMapping("/getUser")
public User getUser(){
   return new User();
}

3、重启查看测试

image-20230802221020536

注:并不是因为@ApiModel这个注解让实体显示在这里了,而是只要出现在接口方法的返回值上的实体都会显示在这里,而@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的。

@ApiModel为类添加注释

@ApiModelProperty为类属性添加注释

3、常用注解

@Api:修饰整个类,描述Controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数描述
@ApiModel:用对象来接收参数
@ApiModelProperty:用对象接收参数时,描述对象的一个字段
@ApiImplicitParam:一个请求参数
@ApiImplicitParams:多个请求参数

下面列一些经常用到的,未列举出来的可以另行查阅说明:

Swagger注解简单说明
@Api(tags = “xxx模块说明”)作用在模块类上
@ApiOperation(“xxx接口说明”)作用在接口方法上
@ApiModel(“xxxPOJO说明”)作用在模型类上:如VO、BO
@ApiModelProperty(value = “xxx属性说明”,hidden = true)作用在类方法和属性上,hidden设置为true可以隐藏该属性
@ApiParam(“xxx参数说明”)作用在参数、方法和字段上,类似@ApiModelProperty

我们也可以给请求的接口配置一些注释

@ApiOperation("狂神的接口")
@PostMapping("/kuang")
@ResponseBody
public String kuang(@ApiParam("这个名字会被返回")String username){
   return username;
}

这样的话,可以给一些比较难理解的属性或者接口,增加一些配置信息,让人更容易阅读!

4、接口调用

使用 swagger 除了让前后端交互变得方便,也让接口的请求变得简单,只需要填写好请求所需要的参数信息,便可直接发起请求。

比如说接口 /user/query-user-info

点击 Try it out

在这里插入图片描述

设置好请求所需的参数,点击 Execute 执行

在这里插入图片描述

就能看到接口响应的结果了

在这里插入图片描述

接口 /user/query-user-infos 也差不多

在这里插入图片描述

在这里插入图片描述

5、进阶使用

1. 添加请求头

有时候我们的接口是需要获取请求头信息的,这样的话就还需要在 swagger 配置中添加请求头的配置。

    @Bean
    public Docket docket() {
        // 设置请求头
        List<Parameter> parameters = new ArrayList<>();
        parameters.add(new ParameterBuilder()
                .name("token") // 字段名
                .description("token") // 描述
                .modelRef(new ModelRef("string")) // 数据类型
                .parameterType("header") // 参数类型
                .defaultValue("default value") // 默认值:可自己设置
                .hidden(true) // 是否隐藏
                .required(false) // 是否必须
                .build());

        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("mike") // 修改组名为 "mike"
                // 配置接口信息
                .select() // 设置扫描接口
                // 配置如何扫描接口
                .apis(RequestHandlerSelectors
                        .basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用
                )
                .paths(PathSelectors
                        .any() // 满足条件的路径,该断言总为true
                )
                .build()

                // 添加请求头参数
                .globalOperationParameters(parameters);
    }

比如接口:

    @GetMapping(value = "/get-token")
    @ApiOperation(value = "获取请求头中的token信息")
    public void getToken(
            @RequestHeader(value = "token",required = false) String token
    ) {
        // 直接获取 token 信息
        System.out.println("token = " + token);

        // 通过代码获取
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (servletRequestAttributes != null) {
            HttpServletRequest request = servletRequestAttributes.getRequest();
            String header = request.getHeader("token");
            System.err.println("header = " + header);
        }
    }

在这里插入图片描述

可以看到这个接口已经可以去设置请求头了,调用接口

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值