Swagger的使用

一、简介

官网:https://swagger.io/

Swagger用于生成、描述、调用和可视化Restful风格的Web服务。Swagger的目标是对REST API定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档和网络流量监测就可以发现和理解服务的能力。

优势:

  • 支持API自动生成同步在线文档:使用Swagger可以直接通过代码生成文档,不需要自己手动编写在线文档。
  • 提供Web页面在线测试API

二、基本使用

1. 导入相关依赖

        <!-- swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spring-web</artifactId>
            <version>2.9.2</version>
        </dependency>
        <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. 编写配置文件

在配置文件config目录下,添加Swagger的配置文件SwaggerConfig.java

@Configuration // 配置类
@EnableSwagger2 // 开启 swagger2 的自动配置
public class SwaggerConfig {}

此时Swagger已经整合到项目之中,可以启动服务。通过输入http://localhost:8080/swagger-ui.html#可以查看swagger文档。

image-20240826101342101

实体类信息会包含接口请求或者相应的实体类信息。

2.1 配置基本信息

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

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

    @Bean
    public Docket docket() {

        // 创建一个 swagger 的 bean 实例
        return new Docket(DocumentationType.SWAGGER_2)
                // 配置基本信息
                .apiInfo(apiInfo());
    }

    // 配置基本信息
    private ApiInfo apiInfo() {
        Contact contact = new Contact(
                "TRR", // 作者姓名
                "https://rrt01.cn", // 作者网站
                "11111111@qq.com"); // 邮箱
        return new ApiInfoBuilder()
                .title("aaa-接口文档") // 标题
                .description("黑暗中的一点光") // 描述
                .termsOfServiceUrl("https://www.baidu.com") //跳转链接
                .version("1.0") // 版本
                .license("Swagger教程")
                .licenseUrl("https://rrt01.cn")
                .contact(contact)
                .build();
    }

2.2 配置接口信息

默认情况下,Swagger会展示所有接口信息。如果希望只显示某些特定接口,可以通过扫描接口来实现。

    @Bean
    public Docket docket() {

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

2.3 配置分组信息

Swagger默认只有一个default分组选项,如果没有设置分组,所有接口都会显示在default分组下。如果想设置分组名称,可以通过.groupName(String )设置。

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

                // 组名
                .groupName("test");               
    }

如果需要配置多个组的话,需要配置多个docket()方法。

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

                // 组名
                .groupName("test1");               
    }

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

                // 组名
                .groupName("test2");               
    }

3. 控制Swagger的开启

不是任何环境下都适合开启swagger,如果在生产环境下开启的话,接口将会暴露出来,具有极大的风险,因此,让swagger根据不同的环境开启也很重要。通过项目的配置文件可以指定选择的环境。application.yml内容如下

spring:
  profiles:
    active: dev

然后可以通过代码判断此时是在什么环境,如果在pro环境,则关闭swagger

    /***
     * swagger配置
     * @param environment
     * @return
     */
    @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)

                // 是否开启swagger
                .enable(flag);

    }

如果application.yml全局配置文件中环境指向pro时,便会提示Could not render e, see the console

4. 常用注解的使用

@ApiModel

该注解是作用于类上面的,用来描述类的一些基本信息。

相关属性

  • value:提供类的一个备用名,如果不设置,默认情况下将使用 class 类的名称
  • description:对于类,提供一个详细的描述信息
  • parent:这个属性用于描述的是类的一些父类信息
  • discriminator:这个属性解释起来比较麻烦,因为这个类主要体现在断言当中
  • subTypes:可以通过这个属性,指定我们想要使用的子类

@ApiModelProperty

该注解用于添加和操作属性模块的数据

相关属性

  • value():参数类型为String,为属性的简要说明
  • name():允许重写属性的名称
  • allowableValues():允许此参数存储的长度
  • access():允许从 API 文件中过滤属性
  • notes():该字段的注释说明
  • dataType():参数的数据类型
  • required():指定参数是否可以为空,默认为false;参数类型boolean
  • position():允许显示地对模型中地属性排序;参数类型int
  • hidden():是否允许模型属性隐藏在Swagger模型定义中,默认为false;参数类型boolean
  • example():属性地示例值
  • readOnly():是否允许将属性指定为只读,默认为false;参数类型boolean
  • reference():指定对对应类型定义的引用,重写指定的任何其他数据名称
  • allowEmptyValue():是否允许传递空值,默认为false;参数类型boolean

示例

  @ApiModelProperty(value = "主键",name = "id",
      allowableValues = "32",
      access = "1",
      notes = "用户的id",
      dataType = "int",
      required = false,
      position = 1,
      hidden = true,
      example = "1",
      readOnly = false,
      reference = "id",
      allowEmptyValue = false)
  @TableId(value = "id",type = IdType.AUTO)
  private int id;

@ApiOperation

该注解用来对某方法/接口进行描述

    @PostMapping(value = "/info")
    @ApiOperation(value = "根据id查询用户详情")
    public ResponseBean queryUserInfo(@RequestBody @Validated IdReq req) {
        return ResponseBean.success(userService.queryUserInfo(req));
    }

@ApiParam

该注解使用在方法或参数上,进行字段说明,是否添加元数据等

相关属性

  • name:参数名
  • value:参数说明
  • required:是否必填
    @PostMapping(value = "/query-user-infos")
    @ApiOperation(value = "条件查询用户信息")
    public ResponseBean queryUserInfos(
            // name 用户名称 不必填
            @ApiParam(value = "用户名称", required = false) @RequestParam(required = false) String name,
            // gender 用户性别 必填
            @ApiParam(value = "用户性别", required = true) @RequestParam(required = true) GenderEnum gender
    ) {
        return ResponseBean.success(userService.queryUserInfos(name,gender));
    }

5. 添加请求头

如果接口需要获取请求头信息,则需要在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.example.demo0.demos.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);
        }
    }

在这里插入图片描述

三、Swagger配置文件

package com.example.demo0.demos.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@Configuration // 配置类
@EnableSwagger2 // 开启 swagger2 的自动配置
public class SwaggerConfig {

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

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

        // 设置请求头
        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)
                // 配置基本信息
                .apiInfo(apiInfo())
                // 组名
                .groupName("test")
                // 配置接口信息
                .select() //设置扫描接口
                // 配置如何扫描接口
                .apis(RequestHandlerSelectors
                        //.any() // 扫描全部的接口,默认
                        //.none() // 全部不扫描
                        .basePackage("com.example.demo0.demos.controller") // 扫描指定包下的接口,最为常用
                        //.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口
                        //.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口
                )
                .paths(PathSelectors
                        .any() // 满足条件的路径,该断言总为true
                        //.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)
                        //.ant("/user/**") // 满足字符串表达式路径
                        //.regex("") // 符合正则的路径
                )
                .build()
                // 是否开启swagger
                .enable(flag)
                // 添加请求头参数
                .globalOperationParameters(parameters);

    }

    // 配置基本信息
    private ApiInfo apiInfo() {
        Contact contact = new Contact(
                "TRR", // 作者姓名
                "https://rrt01.cn", // 作者网站
                "11111115@qq.com"); // 邮箱
        return new ApiInfoBuilder()
                .title("aaa-接口文档") // 标题
                .description("黑暗中的一点光") // 描述
                .termsOfServiceUrl("https://www.baidu.com") //跳转链接
                .version("1.0") // 版本
                .license("Swagger教程")
                .licenseUrl("https://rrt01.cn")
                .contact(contact)
                .build();
    }
}

标签

发表评论