SpringBoot integra el proceso Swagger2, ¡súper detallado!

Bip

prefacio

Este artículo presentará el proceso de integración del marco de visualización de API Swagger en el marco SpringBoot, discutirá los problemas encontrados en el proceso de integración y probará una serie de contenidos de Swagger2.

Breve introducción de Swagger

Swagger es una especificación y un marco completo para generar, describir, invocar y visualizar servicios web RESTful. El objetivo general es que el cliente y el sistema de archivos se actualicen al mismo ritmo que el servidor. La documentación de métodos, parámetros y modelos está estrechamente integrada en el código del lado del servidor, lo que permite que la API permanezca siempre sincronizada. Swagger hace que la administración de implementaciones y el uso de potentes API sean más fáciles que nunca.

Preparación

Antes de comenzar la integración, debe crear un proyecto SpringBoot. Las herramientas y versiones utilizadas en este artículo son las siguientes:

proyecto contenido
IDE entiendo la idea
Java Diez mil años sin cambios Java8
SpringBoot 2.2.5.LIBERACIÓN

Cuando la versión de SpringBoot es superior a 2.6, el método de coincidencia de ruta predeterminado es PathPatternMatcher, mientras que Swagger2 se basa en AntPathMatcher, y habrá una documentaciónPluginsBootstrapper'; la excepción anidada es el error java.lang.NullPointer. Aquí debe prestar atención a la compatibilidad de los dos! ! !

Introducir dependencias

Este artículo discutirá el uso de Maven como una herramienta de administración. Hay dos formas de introducir Swagger2, a saber, el método de inicio y el método de dependencia nativo de Maven.

Dependencias nativas de Maven

Las dependencias de Swagger2 se pueden encontrar en el almacén de Maven . La versión utilizada es 2.9.2y las dependencias se publican aquí:

<!-- swagger start -->
<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>
<!-- swagger end -->

Introducción inicial

Spring-boot-starter-swagger en SpringForAll utiliza la función de configuración automática de Spring Boot para introducir rápidamente swagger2 en la aplicación Spring Boot para generar documentos API y simplificar el código de integración para el uso nativo de swagger2.

Hay una introducción súper detallada y un tutorial de integración en la página de GitHub de spring-boot-starter-swagger, por lo que no entraré en demasiados detalles aquí, y si necesita integrarse de esta manera, vaya a spring-boot -arrancador- arrogancia .

otras dependencias

Lombok

Además de las dependencias de swagger2 y SpringBoot, presentamos Lombok para reducir la escritura de algunos métodos get/set/toString y usar razonablemente las ruedas creadas por los predecesores:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
</dependency>

Por supuesto, no es imposible presentar Lombok cuando se usa IDEA para crear un proyecto.

commons-lang3

Hay una gran cantidad de clases de herramientas en commons-lang3, que también citamos aquí:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.9</version>
</dependency>

configuración

Aquí todavía nos enfocamos en la integración de las dependencias nativas de Maven A diferencia de Starter, que usa archivos de configuración para la configuración, el método nativo debe configurarse usando clases de configuración;

Por supuesto, en este artículo, también usaremos clases de configuración y archivos de configuración juntos, lo que también puede resolver el problema de la configuración inflexible.

SwaggerPropiedades

Aquí encapsulamos los parámetros requeridos por la clase de configuración Swagger2 en la clase de propiedades En el paquete src/main/java, cree un paquete de configuración/propiedades para almacenar la clase de propiedades:

package com.javafeng.boxcloud.config.properties;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.stereotype.Component;

import java.util.List;

@Data
@Component
@ConfigurationProperties(prefix = "swagger")
public class SwaggerProperties {
    
    
    // 是否启用Swagger
    private boolean enable;

    // 扫描的基本包
    @Value("${swagger.base.package}")
    private String basePackage;

    // 联系人邮箱
    @Value("${swagger.contact.email}")
    private String contactEmail;

    // 联系人名称
    @Value("${swagger.contact.name}")
    private String contactName;

    // 联系人网址
    @Value("${swagger.contact.url}")
    private String contactUrl;

    // 描述
    private String description;

    // 标题
    private String title;

    // 网址
    private String url;

    // 版本
    private String version;
}

aplicación.yml

A continuación, configure el archivo de configuración application.yml o application.properties. Este artículo utiliza application.yml, que es coherente con la clase de propiedades:

spring:
  application:
    name: BoxCloud
swagger:
  # 是否启用
  enable: true
  base:
    # 扫描的包,多个包使用逗号隔开
    package: com.javafeng
  contact:
    email: [email protected]
    name: JAVAFENG
    url: https://www.javafeng.com
  description:
  title: ${
    
    spring.spring.name} API Document
  url: https://www.javafeng.com
  version: @project.version@

Swagger2Config

Después de configurar los parámetros, configure Swagger2Config. Aquí, nos referimos al método de configuración de spring-boot-plus y hacemos algunas simplificaciones:

package com.javafeng.boxcloud.config;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.javafeng.boxcloud.config.properties.SwaggerProperties;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.RequestHandler;
import springfox.documentation.annotations.ApiIgnore;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;

@Configuration
@EnableSwagger2
public class Swagger2Config {
    
    
    @Autowired
    private SwaggerProperties swaggerProperties;

    // 扫描多包时,包路径的拆分符,分号
    private static final String SPLIT_COMMA = ",";

    // 扫描多包时,包路径的拆分符,逗号
    private static final String SPLIT_SEMICOLON = ";";

    // Swagger忽略的参数类型
    private Class<?>[] ignoredParameterTypes = new Class[]{
    
    
            ServletRequest.class,
            ServletResponse.class,
            HttpServletRequest.class,
            HttpServletResponse.class,
            HttpSession.class,
            ApiIgnore.class
    };

    @Bean
    public Docket createRestApi() {
    
    
        // 获取需要扫描的包
        String[] basePackages = getBasePackages();
        ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select();
        // 如果扫描的包为空,则默认扫描类上有@Api注解的类
        if (ArrayUtils.isEmpty(basePackages)) {
    
    
            apiSelectorBuilder.apis(RequestHandlerSelectors.withClassAnnotation(Api.class));
        } else {
    
    
            // 扫描指定的包
            apiSelectorBuilder.apis(basePackage(basePackages));
        }
        Docket docket = apiSelectorBuilder.paths(PathSelectors.any())
                .build()
                .enable(swaggerProperties.isEnable())
                .ignoredParameterTypes(ignoredParameterTypes);
        return docket;
    }

    /**
     * 获取apiInfo
     * @return
     */
    private ApiInfo apiInfo() {
    
    
        return new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .termsOfServiceUrl(swaggerProperties.getUrl())
                .contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactUrl(), swaggerProperties.getContactEmail()))
                .version(swaggerProperties.getVersion())
                .build();
    }

    /**
     * 获取扫描的包
     *
     * @return
     */
    public String[] getBasePackages() {
    
    
        String basePackage = swaggerProperties.getBasePackage();
        if (StringUtils.isBlank(basePackage)) {
    
    
            throw new RuntimeException("Swagger basePackage不能为空");
        }
        String[] basePackages = null;
        if (basePackage.contains(SPLIT_COMMA)) {
    
    
            basePackages = basePackage.split(SPLIT_COMMA);
        } else if (basePackage.contains(SPLIT_SEMICOLON)) {
    
    
            basePackages = basePackage.split(SPLIT_SEMICOLON);
        }
        return basePackages;
    }

    public static Predicate<RequestHandler> basePackage(final String[] basePackages) {
    
    
        return input -> declaringClass(input).transform(handlerPackage(basePackages)).or(true);
    }

    private static Function<Class<?>, Boolean> handlerPackage(final String[] basePackages) {
    
    
        return input -> {
    
    
            // 循环判断匹配
            for (String strPackage : basePackages) {
    
    
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
    
    
                    return true;
                }
            }
            return false;
        };
    }
    @SuppressWarnings("deprecation")
    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
    
    
        return Optional.fromNullable(input.declaringClass());
    }
}

mejorado con knife4j

Debido a que la configuración de la mejora es más simple y la eficiencia de su uso es mayor, esta parte del contenido es avanzada. El motivo de no explicarlo junto con el anterior es para distinguir mejor cuáles son de Swagger y cuáles de knife4j, que es más fácil de entender.

En este artículo, integramos knife4j como una mejora de Swagger y agregamos dependencias a pom:

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>2.0.2</version>
</dependency>

Agregue la siguiente configuración en application.yml:

knife4j:
  enable: ${swagger.enable} -- knife4j启用与否取决于Swagger是否启用
  basic:
    enable: true
    username: admin
    password: admin

Modifique Swagger2Config y agregue notas relevantes para habilitar knife4j:

......
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Swagger2Config {
  ......
}

Para una configuración más detallada de knife4j, puede consultar en el sitio web oficial según sea necesario.

Knife4j 2.0.6 o superior, no es necesario usar la anotación @EnableKnife4j, simplemente configure knife4j.enable = true en el archivo de configuración. Para distinguir aquí, 2.0.2 se usa para demostración.

prueba

Después de completar los pasos anteriores, el trabajo de configuración preliminar básicamente ha terminado y puede acceder directamente con un navegador: http://localhost:8080/swagger-ui.html, y aparece la siguiente interfaz para indicar que la configuración está exitoso:

inserte la descripción de la imagen aquí

Debido a que la mejora está configurada, se recomienda usar knife4j para verla, visite http://localhost:8080/doc.html, aparece la siguiente interfaz, que indica que la configuración de la mejora es exitosa (antes de esta página, habrá una página que requiere nombre de usuario y contraseña, siga la configuración Solo complete):

inserte la descripción de la imagen aquí

usar

Las capturas de pantalla en esta parte son capturas de pantalla de la página knife4j, el efecto de visualización y la lógica de la página son más claros.

A continuación, creamos un controlador y declaramos algunas interfaces para probar. Aquí mostraremos cómo usar Swagger2 de manera integral mediante la simulación de funciones como agregar, eliminar, verificar y modificar usuarios, cargar avatares e iniciar sesión. Las anotaciones de Swagger2 que aparecen en la clase se introducirán después de la clase (solo se introducen los atributos comunes, si necesita una investigación más profunda, se recomienda consultar la documentación en el sitio web oficial).

En realidad, hay varias situaciones que deben distinguirse aquí:

  • Si el parámetro de entrada es una clase de entidad
  • Si la respuesta es una clase de entidad

Análisis simple, entre las interfaces Api mencionadas anteriormente:

  • Los parámetros de entrada, como nuevas interfaces, interfaces modificadas e interfaces de inicio de sesión, son clases de entidad, y otros parámetros de entrada son clases que no son de entidad.
  • La respuesta de la interfaz de búsqueda es una clase de entidad, y el resto de las respuestas son clases que no son de entidad.

Según las diferentes situaciones, se utilizan diferentes anotaciones Swagger para el procesamiento.

clase de entidad

import lombok.Data;

@Data
@ApiModel(value = "用户", description = "查询用户")
public class Users {
    
    
    @ApiModelProperty(value = "ID", example = "1")
    private Integer id;
    @ApiModelProperty(value = "用户名")
    private String username;
    @ApiModelProperty(value = "密码")
    private String password;
    @ApiModelProperty(value = "头像")
    private String avatar;

    public Users(Integer id, String username, String password, String avatar) {
    
    
        this.id = id;
        this.username = username;
        this.password = password;
        this.avatar = avatar;
    }

    public Users() {
    
    
    }
}

@ApiModel

Anotaciones/atributos comunes ilustrar
@ApiModel Se utiliza para modificar la clase de entidad (modelo), que puede considerarse como una descripción de la clase de entidad.
 valor Nombre alternativo para el modelo
 descripción Una descripción detallada de la clase.

@ApiModelPropiedad

Anotaciones/atributos comunes ilustrar
@ApiModelPropiedad Se utiliza para modificar campos de clase de entidad, que se pueden considerar como descripciones y restricciones en todos los aspectos de los campos.
 valor Descripción del campo
 nombre El nuevo nombre de campo que anula el nombre de campo original
 ejemplo Valor por defecto (el valor por defecto es "" cuando este campo es de tipo String)
 valores permitidos Limite el rango de valores de este campo, expresado como una lista de valores limitados ({1,2,3}), valor de rango ([1,5]), valor máximo/mínimo (
[1, infinito] infinito o -infinito significa infinito valor)
 requerido Marque si este campo es obligatorio, el valor predeterminado es falso
 oculto Marque si el campo está oculto, predeterminado falso

Cuando se usa la clase de entidad como parámetro de entrada, las anotaciones anteriores se pueden usar para modificar la clase de entidad para lograr el propósito de describir los parámetros de la clase de entidad.

controlador

El controlador aquí se explica por separado según la situación. El primero es la definición de la clase de controlador Controller:

package com.javafeng.boxcloud.controller;

import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
@Api(tags = {
    
    "用户管理"})
public class UsersController {
    
    
   /** 此处编写Api接口方法 **/
   /** --start-- **/
   /** --end-- **/
}
Anotaciones/atributos comunes ilustrar
@Api Se utiliza para decorar el controlador, que se puede considerar como un grupo de interfaz, y la API de esta clase generará documentos automáticamente.
 etiquetas se puede considerar el nombre del grupo de interfaz

La siguiente es la definición del método de interfaz. Al comienzo de esta sección, hemos aprendido acerca de los parámetros centralizados y la respuesta del método de interfaz. Aquí explicaremos estas diferentes situaciones.

  1. Clase de entidad como parámetro de entrada

La nueva interfaz y la interfaz modificada son todas clases de entidad como parámetros de entrada:

@PostMapping("/add")
@ApiOperation(value = "新增用户", notes = "用户不得为空")
public Boolean add(@RequestBody Users user) {
    
    
    return true;
}

@PostMapping("/update")
@ApiOperation(value = "修改用户", notes = "用户不得为空")
public Boolean update(@RequestBody Users user) {
    
    
    return true;
}

@OperaciónApi

Anotaciones/atributos comunes ilustrar
@OperaciónApi Se utiliza para decorar el controlador, que se puede considerar como un grupo de interfaz, y la API de esta clase generará documentos automáticamente.
 valor nombre de la interfaz api
 notas descripción de la interfaz
 etiquetas Defina grupos de interfaces adicionales
Por ejemplo: Incluso si un grupo de interfaces está definido en @Api(tags = 'Administración de usuarios'), se puede especificar otro grupo de interfaces en esta anotación, como @ApiOperation(tags = 'Administración de cuentas'), por lo que que estas interfaces pueden aparecer en ambos grupos de interfaces (Administración de usuarios y Administración de cuentas) al mismo tiempo

Cuando la clase de entidad se usa como parámetro de entrada, hemos introducido las anotaciones y el uso de la descripción del parámetro correspondiente en la parte anterior [Clase de entidad]. Excepto por @ApiOperation, otras anotaciones (@ApiModel, @ApiModelProperty) no se describirán aquí.

inserte la descripción de la imagen aquí

  1. Clase de no entidad como parámetro de entrada

Cuando se utiliza una clase que no es de entidad como parámetro de entrada, se puede subdividir en las siguientes situaciones:

  • parámetros de consulta comunes

Aquí definimos el parámetro de encontrar un determinado usuario como un método Api de parámetros comunes:

@GetMapping("/get")
@ApiOperation(value = "查询单个用户")
@ApiImplicitParams({
    
    
        @ApiImplicitParam(name = "id",
                value = "用户ID",
                required = true,
                paramType = "query"
        )
})
public Users get(@RequestParam("id") Integer id) {
    
    
    return new Users(id, "admin", "123456", "/resource/image/head.png");
}

@ApiImplicitParams y ApiImplicitParam

Anotaciones/atributos comunes ilustrar
@ApiImplicitParams Modifique el método de interfaz Api para declarar parámetros de solicitud
 @ApiImplicitParam Definido en @ApiImplicitParams, cada @ApiImplicitParam corresponde a un parámetro
  nombre Nombre del parámetro
[generalmente corresponde al nombre del parámetro de entrada]
  valor Descripción de parámetros
  requerido Marque si este parámetro es obligatorio, el valor predeterminado es falso
  paramType Marque la posición del parámetro, incluida la ruta, la consulta, el cuerpo, el formulario, el encabezado, etc.
[En general, se recomienda el uso de clases de entidad para el cuerpo y el formulario como parámetros de entrada]

inserte la descripción de la imagen aquí

  • parámetros de ruta
@DeleteMapping("/delete/{id}")
@ApiOperation(value = "删除用户", notes = "用户ID不得为空")
@ApiImplicitParams({
    
    
        @ApiImplicitParam(name = "id",
                value = "用户ID",
                required = true,
                paramType = "path"
        )
})
public Boolean delete(@PathVariable("id") Integer id) {
    
    
    return true;
}

Cuando el parámetro es un parámetro de ruta, el valor paramType de @ApiImplicitParam debe ser ruta y, al mismo tiempo, usar la anotación @PathVariable para modificar el parámetro de ruta.

La anotación @PathVariable puede identificar una plantilla en la URL, como el {id} de la interfaz anterior, y marcar que el parámetro se obtiene en base a la plantilla, que no pertenece a la anotación Swagger, y no se introducirá aquí .

inserte la descripción de la imagen aquí

  • parámetro de encabezado
@PostMapping("/login")
@ApiOperation(value = "登录")
@ApiImplicitParams({
        @ApiImplicitParam(name = "username",
                value = "用户名",
                required = true,
                paramType = "header"
        ),
        @ApiImplicitParam(name = "password",
                value = "密码",
                required = true,
                paramType = "header"
        )
})
public Boolean login(@RequestHeader("username") String username,@RequestHeader("password")  String password) {
    System.out.println(username + password);
    return true;
}

Cuando el parámetro es un parámetro de ruta, el valor paramType de @ApiImplicitParam debe ser el encabezado. Al mismo tiempo, use la anotación @RequestHeader para modificar el parámetro y marque la posición de adquisición del parámetro como obtenido del encabezado, de modo que SpringMVC puede obtenerlo correctamente del parámetro Header.

inserte la descripción de la imagen aquí

  • parámetros de archivo

Aquí explicamos directamente una situación compleja, es decir, considere incluir parámetros de archivo y parámetros comunes al mismo tiempo, y modifíquelos según sea necesario durante el proceso de desarrollo real.

@PostMapping("/upload")
@ApiOperation(value = "上传头像", notes = "参数需要头像文件以及对应用户ID")
@ApiImplicitParams({
    
    
        @ApiImplicitParam(name = "id",
                value = "该头像对应的用户ID",
                required = true
        )
})
public Boolean upload(@ApiParam(value = "图片文件", required = true) @RequestParam("avatar") MultipartFile avatar, @RequestParam("id") Integer id) {
    
    
    System.out.println(avatar);
    return true;
}

对于非文件参数的普通参数,参照第一条【普通查询参数】中的声明方式即可;

对于文件参数,则需要使用@ApiParam对参数进行修饰;

@ApiParam

注解/常用属性 说明
@ApiImplicitParams 修饰Api接口方法,用来声明请求参数
 value 参数名称
 required 标记该参数是否必需,默认false
 allowMultiple 是否允许多个文件,默认false

同样的,需要在参数上使用@RequestParam进行修饰。

inserte la descripción de la imagen aquí

这里插入一个解释,就是对于同时出现Swagger注解(一般以Api作为前缀)和非Swagger注解同时对参数进行修饰时,并不会彼此影响,Swagger注解只是用来对Api方法进行描述,并不会对该方法造成实质影响,

而例如@RequestParam、@RequestHeader在内的注解是决定SpringMVC是否能正确读取到参数的关键

这里对于两种注解之间的侵入性,掘金大佬1黄鹰在其源码剖析@ApiImplicitParam对@RequestParam的required属性的侵入性做了深入剖析,感兴趣的可以去看看

  1. 实体类作为响应

当实体类作为响应时,通常在实体类上的注解所生成的描述也会作为响应的描述出现,在此处不再进行赘述。

inserte la descripción de la imagen aquí

  1. 非实体类作为响应

我们对新增接口进行修改,在其方法上添加@ApiResponses来对响应进行描述:

@PostMapping("/add")
@ApiOperation(value = "新增用户", notes = "用户不得为空")
@ApiResponses({
        @ApiResponse(code = 200, message = "添加成功"),
        @ApiResponse(code = 500, message = "服务器错误"),
        @ApiResponse(code = 400, message = "参数异常")
})
public Boolean add(@RequestBody Users user) {
    return true;
}

需要注意的是,Swagger无法对非实体类响应进行详细描述,只能通过@ApiResponses和@ApiResponse描述响应码信息。同时,在以实体类作为响应时,同样可也以使用@ApiResponses和@ApiResponse。

inserte la descripción de la imagen aquí

Token处理

在做前后端分离的应用时,后端接口通常会要求在Header中添加Token以保证安全性,这里我们依然是参考SpringBootPlus的处理方式,对Token进行处理。

需要注意的是,此处的Token处理是基于Swagger进行接口测试时的,并不是对接口如何增加Token进行讲解,只是对有Token的接口如何通过Swagger进行测试做出讲解。

修改SwaggerProperties

思路是,在Swagger配置中添加默认的全局参数描述,对Token进行处理,这里我们默认Token信息附加在Header中。

首先在SwaggerProperties中新增以下内容:

@NestedConfigurationProperty
private List<ParameterConfig> parameterConfig;

// 自定义参数配置
@Data
public static class ParameterConfig {
    
    
    // 名称
    private String name;
    // 描述
    private String description;
    // 参数类型
    // header, cookie, body, query
    private String type = "head";
    // 数据类型
    private String dataType = "String";
    // 是否必填
    private boolean required;
    // 默认值
    private String defaultValue;
}

修改application.yml

随后在application.yml中对新增部分编写对应的配置项,这里贴出整体内容,自定义参数配置部分为新增内容:

spring:
  application:
    name: BoxCloud
    
swagger:
  enable: true
  base:
    package: com.javafeng
  contact:
    email: [email protected]
    name: JAVAFENG
    url: https://www.javafeng.com
  description:
  title: ${spring.application.name} API Document
  url: https://www.javafeng.com
  version: @project.version@
  # 自定义参数配置,可配置N个
  parameter-config:
    - name: token
      description: Token Request Header
      # header, cookie, body, query
      type: header
      data-type: String
      required: false
      # 测试接口时,自动填充token的值
      default-value:
      
knife4j:
  enable: ${swagger.enable}
  basic:
    enable: true
    username: admin
    password: admin

这里可以根据不同的需求,配置多个自定义参数,这里只演示了Token一个参数,如果是多个参数的话,配置多个即可,如下:

parameter-config:
   - name: param1
     description: This is param1
     type: header
     data-type: String
     required: false
     default-value:
 parameter-config:
   - name: param2
     description: This is param2
     type: header
     data-type: String
     required: false
     default-value:
 parameter-config:
   - name: param3
     description: This is param3
     type: header
     data-type: String
     required: false
     default-value:

修改Swagger2Config

接下来,我们在Swagger2Config中对Token参数进行处理,首先在Swagger2Config中添加如下方法,从application.yml中获取到配置的额外Token参数并进行封装:

/**
 * 添加额外参数
 *
 * @return
 */
private List<Parameter> getParameters() {
    
    
    // 获取自定义参数配置
    List<SwaggerProperties.ParameterConfig> parameterConfig = swaggerProperties.getParameterConfig();
    if (CollectionUtils.isEmpty(parameterConfig)) {
    
    
        return null;
    }
    List<Parameter> parameters = new ArrayList<>();
    parameterConfig.forEach(parameter -> {
    
    
        // 设置自定义参数
        parameters.add(new ParameterBuilder()
                .name(parameter.getName())
                .description(parameter.getDescription())
                .modelRef(new ModelRef(parameter.getDataType()))
                .parameterType(parameter.getType())
                .required(parameter.isRequired())
                .defaultValue(parameter.getDefaultValue())
                .build());
    });
    return parameters;
}

随后修改createRestApi方法,在声明Docket的位置添加对额外参数的处理,添加后如下:

... ...
Docket docket = apiSelectorBuilder.paths(PathSelectors.any())
        .build()
        .enable(swaggerProperties.isEnable())
        .ignoredParameterTypes(ignoredParameterTypes)
        .globalOperationParameters(getParameters()); // 此处为新增
... ...

重启项目后,我们随意打开一个接口的文档,这里我们打开的是knife4j的页面,选择调试,在请求头部位置就可以看到Token的相关内容:

inserte la descripción de la imagen aquí

当然,在Swagger的原生界面也可以看到:

inserte la descripción de la imagen aquí

参考和引用

  1. dynamicbeamswagger2常用注解API,来源 CSDN
  2. 随风行云Spring Boot整合swagger使用教程,来源 CNBLOG
  3. 1 Águila amarilla : análisis del código fuente de la intrusión de @ApiImplicitParam del atributo requerido de @RequestParam , fuente Nuggets
  4. SpringBootPlus

Supongo que te gusta

Origin blog.csdn.net/u012751272/article/details/127101042
Recomendado
Clasificación