当前位置:首页 > 单片机 > 架构师社区
[导读]目录前言官方文档如何说?SpringBoot版本说明添加依赖springfox-boot-starter做了什么?撸起袖子就是干?定制一个基本的文档示例文档如何分组?如何添加授权信息?如何携带公共的请求参数?粗略是一个BUG总结前言最近频繁被Swagger3.0刷屏,官方表示这是...

目录

  • 前言
  • 官方文档如何说?
  • Spring Boot版本说明
  • 添加依赖
  • springfox-boot-starter做了什么?
  • 撸起袖子就是干?
    • 定制一个基本的文档示例
    • 文档如何分组?
    • 如何添加授权信息?
    • 如何携带公共的请求参数?
  • 粗略是一个BUG
  • 总结

前言

最近频繁被ge: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;">Swagger 3.0刷屏,官方表示这是一个突破性的变更,有很多的亮点,我还真不太相信,今天来带大家尝尝鲜,看看这碗汤到底鲜不鲜....

官方文档如何说?

该项目开源在Github上,地址:https://github.com/springfox/springfox。

Swagger 3.0有何改动?官方文档总结如下几点:

  1. 删除了对springfox-swagger2的依赖
  2. 删除所有@EnableSwagger2...注解
  3. 添加了springfox-boot-starter依赖项
  4. 移除了guava等第三方依赖
  5. 文档访问地址改变了,改成了http://ip:port/project/swagger-ui/index.html
姑且看到这里,各位初始感觉如何?

Swagger3.0 天天刷屏,真的香吗?
既然人家更新出来了,咱不能不捧场,下面就介绍下Spring Boot如何整合Swagger 3.0吧。

Spring Boot版本说明

作者使用Spring Boot的版本是2.3.5.RELEASE

添加依赖

Swagger 3.0已经有了与Spring Boot整合的启动器,只需要添加以下依赖:

  <dependency>
       <groupId>io.springfoxgroupId>
       <artifactId>springfox-boot-starterartifactId>
       <version>3.0.0version>
  dependency>

springfox-boot-starter做了什么?

Swagger 3.0主推的一大特色就是这个启动器,那么这个启动器做了什么呢?

「记住」:启动器的一切逻辑都在自动配置类中。

找到springfox-boot-starter的自动配置类,在/META-INF/spring.factories文件中,如下:

Swagger3.0 天天刷屏,真的香吗?
从上图可以知道,自动配置类就是OpenApiAutoConfiguration,源码如下:

@Configuration
@EnableConfigurationProperties(SpringfoxConfigurationProperties.class)
@ConditionalOnProperty(value 
"springfox.documentation.enabled", havingValue = "true", matchIfMissing = true)
@Import({
    OpenApiDocumentationConfiguration.class,
    SpringDataRestConfiguration.class,
    BeanValidatorPluginsConfiguration.class,
    Swagger2DocumentationConfiguration.class,
    SwaggerUiWebFluxConfiguration.class,
    SwaggerUiWebMvcConfiguration.class
})
@AutoConfigureAfter(
{ WebMvcAutoConfiguration.classJacksonAutoConfiguration.class,
    HttpMessageConvertersAutoConfiguration.classRepositoryRestMvcAutoConfiguration.class })
public class OpenApiAutoConfiguration 
{

}
敢情这个自动配置类啥也没干,就光导入了几个配置类(@Import)以及开启了属性配置(@EnableConfigurationProperties)。

Swagger3.0 天天刷屏,真的香吗?
「重点」:记住OpenApiDocumentationConfiguration这个配置类,初步看来这是个BUG,本人也不想深入,里面的代码写的实在拙劣,注释都不写。

撸起袖子就是干?

说真的,还是和以前一样,真的没什么太大的改变,按照文档的步骤一步步来。

定制一个基本的文档示例

一切的东西还是需要配置类手动配置,说真的,我以为会在全局配置文件中自己配置就行了。哎,想多了。配置类如下:

@EnableOpenApi
@Configuration
@EnableConfigurationProperties(value = {SwaggerProperties.class})
public class SwaggerConfig 
{
  /**
     * 配置属性
     */

    @Autowired
    private SwaggerProperties properties;

    @Bean
    public Docket frontApi() {
        return new Docket(DocumentationType.OAS_30)
                //是否开启,根据环境配置
                .enable(properties.getFront().getEnable())
                .groupName(properties.getFront().getGroupName())
                .apiInfo(frontApiInfo())
                .select()
                //指定扫描的包
                .apis(RequestHandlerSelectors.basePackage(properties.getFront().getBasePackage()))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 前台API信息
     */

    private ApiInfo frontApiInfo() {
        return new ApiInfoBuilder()
                .title(properties.getFront().getTitle())
                .description(properties.getFront().getDescription())
                .version(properties.getFront().getVersion())
                .contact(    //添加开发者的一些信息
                        new Contact(properties.getFront().getContactName(), properties.getFront().getContactUrl(),
                                properties.getFront().getContactEmail()))
                .build();
    }
}
@EnableOpenApi这个注解文档解释如下:

Indicates that Swagger support should be enabled.
This should be applied to a Spring java config and should have an accompanying '@Configuration' annotation.
Loads all required beans defined in @see SpringSwaggerConfig
什么意思呢?大致意思就是「只有在配置类标注了@EnableOpenApi这个注解才会生成Swagger文档」

@EnableConfigurationProperties这个注解使开启自定义的属性配置,这是作者自定义的Swagger配置。

总之还是和之前一样配置,根据官方文档要求,需要在配置类上加一个@EnableOpenApi注解。

文档如何分组?

我们都知道,一个项目可能分为前台后台APP端小程序端.....每个端的接口可能还相同,不可能全部放在一起吧,肯定是要区分开的。

因此,实际开发中文档肯定是要分组的。

分组其实很简单,SwaggerIOC中注入一个Docket即为一个组的文档,其中有个groupName()方法指定分组的名称。

因此只需要注入多个Docket指定不同的组名即可,当然,这些文档的标题、描述、扫描的路径都是可以不同定制的。

如下配置两个Docket,分为前台和后台,配置类如下:

@EnableOpenApi
@Configuration
@EnableConfigurationProperties(value = {SwaggerProperties.class})
public class SwaggerConfig 
{
  /**
     * 配置属性
     */

    @Autowired
    private SwaggerProperties properties;

    @Bean
    public Docket frontApi() {
        return new Docket(DocumentationType.OAS_30)
                //是否开启,根据环境配置
                .enable(properties.getFront().getEnable())
                .groupName(properties.getFront().getGroupName())
                .apiInfo(frontApiInfo())
                .select()
                //指定扫描的包
                .apis(RequestHandlerSelectors.basePackage(properties.getFront().getBasePackage()))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 前台API信息
     */

    private ApiInfo frontApiInfo() {
        return new ApiInfoBuilder()
                .title(properties.getFront().getTitle())
                .description(properties.getFront().getDescription())
                .version(properties.getFront().getVersion())
                .contact(    //添加开发者的一些信息
                        new Contact(properties.getFront().getContactName(), properties.getFront().getContactUrl(),
                                properties.getFront().getContactEmail()))
                .build();
    }
    
    /**
     * 后台API
     */

    @Bean
    public Docket backApi() {
        return new Docket(DocumentationType.OAS_30)
                //是否开启,根据环境配置
                .enable(properties.getBack().getEnable())
                .groupName("后台管理")
                .apiInfo(backApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage(properties.getBack().getBasePackage()))
                .paths(PathSelectors.any())
                .build();
    }
    
    /**
     * 后台API信息
     */

    private ApiInfo backApiInfo() {
        return new ApiInfoBuilder()
                .title(properties.getBack().getTitle())
                .description(properties.getBack().getDescription())
                .version(properties.getBack().getVersion())
                .contact(    //添加开发者的一些信息
                        new Contact(properties.getBack().getContactName(), properties.getBack().getContactUrl(),
                                properties.getBack().getContactEmail()))
                .build();
    }
    
}
属性配置文件SwaggerProperties如下,分为前台和后台两个不同属性的配置:

/**
 * swagger的属性配置类
 */

@ConfigurationProperties(prefix = "spring.swagger")
@Data
public class SwaggerProperties {

    /**
     * 前台接口配置
     */

    private SwaggerEntity front;

    /**
     * 后台接口配置
     */

    private SwaggerEntity back;

    @Data
    public static class SwaggerEntity {
        private String groupName;
        private String basePackage;
        private String title;
        private String description;
        private String contactName;
        private String contactEmail;
        private String contactUrl;
        private String version;
        private Boolean enable;
    }
}
此时的文档截图如下,可以看到有了两个不同的分组:

Swagger3.0 天天刷屏,真的香吗?

如何添加授权信息?

现在项目API肯定都需要权限认证,否则不能访问,比如请求携带一个TOKEN

在Swagger中也是可以配置认证信息,这样在每次请求将会默认携带上。

Docket中有如下两个方法指定授权信息,分别是securitySchemes()securityContexts()。在配置类中的配置如下,在构建Docket的时候设置进去即可:


    @Bean
    public Docket frontApi() {
        RequestParameter parameter = new RequestParameterBuilder()
                .name("platform")
                .description("请求头")
                .in(ParameterType.HEADER)
                .required(true)
                .build();
        List parameters = Collections.singletonList(parameter);
        return new Docket(DocumentationType.OAS_30)
                //是否开启,根据环境配置
                .enable(properties.getFront().getEnable())
                .groupName(properties.getFront().getGroupName())
                .apiInfo(frontApiInfo())
                .select()
                //指定扫描的包
                .apis(RequestHandlerSelectors.basePackage(properties.getFront().getBasePackage()))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    /**
     * 设置授权信息
     */

    private List securitySchemes() {
        ApiKey apiKey = new ApiKey("BASE_TOKEN""token", In.HEADER.toValue());
        return Collections.singletonList(apiKey);
    }

    /**
     * 授权信息全局应用
     */

    private List securityContexts() {
        return Collections.singletonList(
                SecurityContext.builder()
                        .securityReferences(Collections.singletonList(new SecurityReference("BASE_TOKEN"new AuthorizationScope[]{new AuthorizationScope("global""")})))
                        .build()
        );
    }
以上配置成功后,在Swagger文档的页面中将会有Authorize按钮,只需要将请求头添加进去即可。如下图:

Swagger3.0 天天刷屏,真的香吗?

如何携带公共的请求参数?

不同的架构可能发请求的时候除了携带TOKEN,还会携带不同的参数,比如请求的平台,版本等等,这些每个请求都要携带的参数称之为公共参数。

那么如何在Swagger中定义公共的参数呢?比如在请求头中携带。

Docket中的方法globalRequestParameters()可以设置公共的请求参数,接收的参数是一个List,因此只需要构建一个RequestParameter集合即可,如下:

@Bean
public Docket frontApi() {
   //构建一个公共请求参数platform,放在在header
   RequestParameter parameter = new RequestParameterBuilder()
      //参数名称
      .name("platform")
      //描述
      .description("请求的平台")
      //放在header中
      .in(ParameterType.HEADER)
      //是否必传
      .required(true)
      .build();
      //构建一个请求参数集合
      List parameters = Collections.singletonList(parameter);
        return new Docket(DocumentationType.OAS_30)
                .....
                .build()
                .globalRequestParameters(parameters);
    }
以上配置完成,将会在每个接口中看到一个请求头,如下图:

Swagger3.0 天天刷屏,真的香吗?

粗略是一个BUG

作者在介绍自动配置类的时候提到了一嘴,现在来简单分析下。

OpenApiAutoConfiguration这个自动配置类中已经导入OpenApiDocumentationConfiguration这个配置类,如下一段代码:

@Import({
    OpenApiDocumentationConfiguration.class,
    ......
})
@EnableOpenApi的源码如下:

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = {java.lang.annotation.ElementType.TYPE})
@Documented
@Import(OpenApiDocumentationConfiguration.class)
public @interface EnableOpenApi 
{
}
从源码可以看出:@EnableOpenApi这个注解的作用就是导入OpenApiDocumentationConfiguration这个配置类,纳尼???

既然已经在自动配置类OpenApiAutoConfiguration导入了,那么无论需不需要在配置类上标注@EnableOpenApi注解不都会开启Swagger支持吗?

「测试一下」:不在配置类上标注@EnableOpenApi这个注解,看看是否Swagger运行正常。结果在意料之中,还是能够正常运行。

「总结」:作者只是大致分析了下,这可能是个BUG亦或是后续有其他的目的,至于结果如此,不想验证了,没什么意思。

总结

这篇文章也是尝了个鲜,个人感觉不太香,有点失望。你喜欢吗?


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭