O SpringBoot integra o processo Swagger2, super detalhado!

Bip

prefácio

Este artigo apresentará o processo de integração do framework de visualização da API Swagger no framework SpringBoot, discutirá os problemas encontrados no processo de integração e testará uma série de conteúdos do Swagger2.

Breve introdução do Swagger

Swagger é uma especificação e um framework completo para gerar, descrever, invocar e visualizar serviços web RESTful. O objetivo geral é fazer com que o cliente e o sistema de arquivos sejam atualizados na mesma taxa que o servidor. A documentação de métodos, parâmetros e modelos é totalmente integrada ao código do lado do servidor, permitindo que a API permaneça sempre sincronizada. O Swagger torna o gerenciamento de implantação e o uso de APIs poderosas mais fácil do que nunca.

Preparação

Antes de iniciar a integração, você precisa criar um projeto SpringBoot. As ferramentas e versões utilizadas neste artigo são as seguintes:

projeto contente
IDE eu entendo a ideia
Java Dez mil anos inalterado Java8
SpringBoot 2.2.5.LIBERAÇÃO

Quando a versão do SpringBoot for superior a 2.6, o método de correspondência de caminho padrão é PathPatternMatcher, e Swagger2 é baseado em AntPathMatcher, e haverá uma exceção documentalPluginsBootstrapper'; aninhada é o erro java.lang.NullPointer. Aqui, precisamos prestar atenção ao a compatibilidade dos dois! ! !

Introduzir dependências

Este artigo discutirá o uso do Maven como uma ferramenta de gerenciamento. Há duas maneiras de introduzir o Swagger2, ou seja, o método inicial e o método de dependência nativo do Maven.

Dependências nativas do Maven

As dependências do Swagger2 podem ser encontradas no warehouse do Maven . A versão utilizada é 2.9.2, e as dependências estão postadas aqui:

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

Introdução inicial

O spring-boot-starter-swagger em SpringForAll usa o recurso de configuração automática do Spring Boot para introduzir rapidamente o swagger2 no aplicativo de inicialização de primavera para gerar documentos de API e simplificar o código de integração para uso nativo do swagger2.

Há uma introdução superdetalhada e um tutorial de integração na página GitHub de spring-boot-starter-swagger, então não vou entrar em muitos detalhes aqui, e se você precisar integrar dessa forma, vá para spring-boot -starter- arrogância .

outras dependências

Lombok

Além das dependências de swagger2 e SpringBoot, introduzimos o Lombok para reduzir a escrita de alguns métodos get/set/toString e usar razoavelmente as rodas feitas pelos predecessores:

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

Obviamente, não é impossível introduzir o Lombok ao usar o IDEA para criar um projeto.

commons-lang3

Há um grande número de classes de ferramentas em commons-lang3, que também citamos aqui:

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

configuração

Aqui ainda focamos na integração das dependências nativas do Maven. Ao contrário do Starter, que usa arquivos de configuração para configuração, o método nativo precisa ser configurado usando classes de configuração;

É claro que neste artigo também usaremos classes de configuração e arquivos de configuração juntos, o que também pode resolver o problema de configuração inflexível.

SwaggerProperties

Aqui encapsulamos os parâmetros exigidos pela classe de configuração Swagger2 na classe Properties. No pacote src/main/java, crie um pacote config/properties para armazenar a classe Properties:

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;
}

aplicativo.yml

Em seguida, configure o arquivo de configuração application.yml ou application.properties. Este artigo usa application.yml, que é consistente com a classe Properties:

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

Depois de configurados os parâmetros, configure o Swagger2Config. Aqui, nos referimos ao método de configuração do spring-boot-plus e fazemos algumas simplificações:

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());
    }
}

faca4j aprimorada

Como a configuração do aprimoramento é mais simples e a eficiência de uso do aprimoramento é maior, esta parte do conteúdo é avançada. O motivo de não explicá-lo junto com o anterior é para distinguir melhor quais são do Swagger e quais são do knife4j, que fica mais fácil de entender.

Neste artigo, integramos o knife4j como um aprimoramento do Swagger e adicionamos dependências ao pom:

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

Adicione a seguinte configuração em application.yml:

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

Modifique Swagger2Config e adicione notas relevantes para habilitar o knife4j:

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

Para uma configuração mais detalhada do knife4j, você pode verificar no site oficial conforme necessário.

Knife4j 2.0.6 ou superior, não há necessidade de usar a anotação @EnableKnife4j, basta configurar o knife4j.enable = true no arquivo de configuração. Para distinguir aqui, 2.0.2 é usado para demonstração.

teste

Após a conclusão das etapas acima, o trabalho de configuração preliminar está basicamente concluído e você pode acessá-lo diretamente com um navegador: http://localhost:8080/swagger-ui.html, e a seguinte interface aparece para indicar que a configuração está bem-sucedido:

insira a descrição da imagem aqui

Como o aprimoramento está configurado, é recomendável usar o knife4j para visualizá-lo, acesse http://localhost:8080/doc.html, aparecerá a seguinte interface, indicando que a configuração do aprimoramento foi bem-sucedida (antes desta página, haverá um página que requer nome de usuário e senha, siga a configuração Basta preencher):

insira a descrição da imagem aqui

usar

As capturas de tela nesta parte são capturas de tela da página knife4j, o efeito de exibição e a lógica da página são mais claros

Em seguida, criamos um Controller e declaramos algumas interfaces para teste. Aqui mostraremos como usar o Swagger2 de maneira geral, simulando funções como adicionar, excluir, verificar e modificar usuários, fazer upload de avatares e fazer login. As anotações do Swagger2 que aparecem na aula serão introduzidas após a aula (só são introduzidos atributos comuns, caso precise de uma pesquisa mais aprofundada, é recomendável consultar a documentação no site oficial).

Na verdade, existem várias situações que precisam ser distinguidas aqui:

  • Se o parâmetro de entrada é uma classe de entidade
  • Se a resposta é uma classe de entidade

Análise simples, entre as interfaces API mencionadas acima:

  • Nova interface, interface modificada, interface de login e outros parâmetros de entrada são classes de entidade e outros parâmetros de entrada são classes que não são de entidade
  • A resposta da interface de pesquisa é uma classe de entidade e o restante das respostas são classes sem entidade

De acordo com diferentes situações, diferentes anotações do Swagger são usadas para processamento.

Classe de entidade

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

Anotações/atributos comuns ilustrar
@ApiModel É usado para modificar a classe de entidade (modelo), que pode ser considerada como uma descrição da classe de entidade
 valor Nome alternativo para o modelo
 descrição Uma descrição detalhada da classe

@ApiModelProperty

Anotações/atributos comuns ilustrar
@ApiModelProperty Usado para modificar campos de classe de entidade, que podem ser considerados como descrições e restrições em todos os aspectos dos campos
 valor Descrição do campo
 nome O novo nome de campo que substitui o nome de campo original
 exemplo Valor padrão (o valor padrão é "" quando este campo é do tipo String)
 valores permitidos Limite o intervalo de valores deste campo, expresso como uma lista de valores limitados ({1,2,3}), valor do intervalo ([1,5]), valor máximo/mínimo (
[1, infinito] infinito ou -infinito significa infinito valor)
 obrigatório Marque se este campo é obrigatório, o padrão é falso
 escondido Marque se o campo está oculto, padrão falso

Ao usar a classe de entidade como um parâmetro de entrada, as anotações acima podem ser usadas para modificar a classe de entidade para atingir o objetivo de descrever os parâmetros de classe de entidade.

controlador

O controlador aqui é explicado separadamente de acordo com a situação. O primeiro é a definição da classe do 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-- **/
}
Anotações/atributos comuns ilustrar
@Api Ele é usado para decorar o Controller, que pode ser considerado como um grupo de interface, e a API desta classe irá gerar documentos automaticamente
 Tag pode ser considerado o nome do grupo de interface

Em seguida é a definição do método de interface.No início desta seção, aprendemos sobre os parâmetros centralizados e resposta do método de interface.Aqui vamos explicar essas diferentes situações.

  1. Classe de entidade como parâmetro de entrada

A nova interface e a interface modificada são todas classes de entidade 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;
}

@ApiOperation

Anotações/atributos comuns ilustrar
@ApiOperation Ele é usado para decorar o Controller, que pode ser considerado como um grupo de interface, e a API desta classe irá gerar documentos automaticamente
 valor Nome da interface da API
 notas descrição da interface
 Tag Definir grupos de interface adicionais
Por exemplo: Mesmo que um grupo de interface seja definido em @Api(tags = 'User Management'), outro grupo de interface pode ser especificado nesta anotação, como @ApiOperation(tags = 'Account Management'), então que essas Interfaces podem aparecer em ambos os grupos de interface (Gerenciamento de usuários e Gerenciamento de contas) ao mesmo tempo

Quando a classe de entidade é usada como um parâmetro de entrada, introduzimos as anotações e uso de descrição do parâmetro correspondente na parte anterior [Classe de entidade]. Exceto para @ApiOperation, outras anotações (@ApiModel, @ApiModelProperty) não serão descritas aqui.

insira a descrição da imagem aqui

  1. Classe não entidade como parâmetro de entrada

Quando uma classe não entidade é utilizada como parâmetro de entrada, ela pode ser subdividida nas seguintes situações:

  • parâmetros de consulta comuns

Aqui definimos o parâmetro de localização de um determinado usuário como um método Api de parâmetros comuns:

@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 e ApiImplicitParam

Anotações/atributos comuns ilustrar
@ApiImplicitParams Modifique o método de interface API para declarar parâmetros de solicitação
 @ApiImplicitParam Definido em @ApiImplicitParams, cada @ApiImplicitParam corresponde a um parâmetro
  nome Nome do parâmetro
[geralmente corresponde ao nome do parâmetro de entrada]
  valor Descrição do parâmetro
  obrigatório Marque se este parâmetro é obrigatório, o padrão é false
  paramType Marque a posição do parâmetro, incluindo caminho, consulta, corpo, formulário, cabeçalho, etc.
[Em geral, corpo e formulário são recomendados para usar classes de entidade como parâmetros de entrada]

insira a descrição da imagem aqui

  • parâmetros de caminho
@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;
}

Quando o parâmetro é um parâmetro de caminho, o valor paramType de @ApiImplicitParam deve ser caminho e, ao mesmo tempo, usar a anotação @PathVariable para modificar o parâmetro de caminho.

A anotação @PathVariable pode identificar um template na URL, como o {id} da interface acima, e marcar que o parâmetro é obtido com base no template, que não pertence à anotação Swagger, e não será introduzido aqui .

insira a descrição da imagem aqui

  • parâmetro de cabeçalho
@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;
}

Quando o parâmetro é um parâmetro de caminho, o valor paramType de @ApiImplicitParam deve ser cabeçalho. Ao mesmo tempo, use a anotação @RequestHeader para modificar o parâmetro e marque a posição de aquisição do parâmetro conforme obtido do cabeçalho, para que SpringMVC pode obtê-lo corretamente do parâmetro Header.

insira a descrição da imagem aqui

  • parâmetros de arquivo

Aqui explicamos diretamente uma situação complexa, ou seja, considere incluir parâmetros de arquivo e parâmetros comuns ao mesmo tempo e modifique-os conforme necessário durante o processo de desenvolvimento 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进行修饰。

insira a descrição da imagem aqui

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

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

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

  1. 实体类作为响应

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

insira a descrição da imagem aqui

  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。

insira a descrição da imagem aqui

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的相关内容:

insira a descrição da imagem aqui

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

insira a descrição da imagem aqui

参考和引用

  1. dynamicbeamswagger2常用注解API,来源 CSDN
  2. 随风行云Spring Boot整合swagger使用教程,来源 CNBLOG
  3. 1 Yellow Eagle : análise do código-fonte da intrusão de @ApiImplicitParam do atributo obrigatório de @RequestParam , source Nuggets
  4. SpringBootPlus

Acho que você gosta

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