天天看點

Spring Boot 進階-詳解Spring Boot中使用Swagger3.0

Spring Boot 進階-詳解Spring Boot中使用Swagger3.0

在上篇文章中我們介紹了Spring Boot 整合Swagger3.0的一些基礎用法,這篇文章中我們來深入學習一下Swagger3.0 還有其他進階用法。

在日常的開發中,為了減少工作量,我們會遇到一種情況,就是将前端的接口與後端的接口編寫到同一個代碼中,這樣也提高了代碼的複用率,減少了重複開發代碼的工作量。這個時候我們就需要将接口文檔也進行拆分。分為前端接口和後端接口兩個部分。

在Swagger3.0中如何進行接口分組呢?

Swagger3.0 接口分組操作

通過之前的例子我們知道,我們往容器中注入一個Docket就是注入了一個文檔,其中我們設定了groupName的分組名稱。要想注入多個文檔,意思就是需要往容器中注入多個Docket。既然是這樣,我們就需要修改之前的Swagger的配置檔案,将其改為如下的代碼。

@EnableOpenApi
@Configuration
@EnableConfigurationProperties(value = {SwaggerProperties.class})
public class Swagger3Config {

    @Autowired
    private SwaggerProperties swaggerProperties;

    @Bean
    public Docket frontApi(){
        return new Docket(DocumentationType.OAS_30)
                // 是否開啟,根據環境配置
                .enable(swaggerProperties.getFront().getEnable())
                .groupName(swaggerProperties.getFront().getGroupName())
                .apiInfo(frontApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getFront().getBasePackege()))
                .paths(PathSelectors.any())
                .build();
    }

    // 前台API資訊
    private ApiInfo frontApiInfo(){
        return new ApiInfoBuilder()
                .title(swaggerProperties.getFront().getTitle())
                .description(swaggerProperties.getFront().getDescription())
                .version(swaggerProperties.getFront().getVersion())
                .contact(
                        // 添加開發者資訊
                        new Contact(
                                swaggerProperties.getFront().getContactName(),
                                swaggerProperties.getFront().getContactUrl(),
                                swaggerProperties.getFront().getContactEmail())
                ).build();
    }


    @Bean
    public Docket backApi(){
        return new Docket(DocumentationType.OAS_30)
                // 是否開啟,根據環境配置
                .enable(swaggerProperties.getBack().getEnable())
                .groupName(swaggerProperties.getBack().getGroupName())
                .apiInfo(backApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBack().getBasePackege()))
                .paths(PathSelectors.any())
                .build();
    }

    // 前台API資訊
    private ApiInfo backApiInfo(){
        return new ApiInfoBuilder()
                .title(swaggerProperties.getBack().getTitle())
                .description(swaggerProperties.getBack().getDescription())
                .version(swaggerProperties.getBack().getVersion())
                .contact(
                        // 添加開發者資訊
                        new Contact(
                                swaggerProperties.getBack().getContactName(),
                                swaggerProperties.getBack().getContactUrl(),
                                swaggerProperties.getBack().getContactEmail())
                ).build();
    }

}           

我們會看到在這個配置類中注入了兩個Docket,分别代表前端的接口和後端的接口,那麼在配置檔案中如何進行配置呢?

首先我們先來看一下其配置類,代碼如下

@Data
@ConfigurationProperties(prefix = "spring.swagger3")
public class SwaggerProperties {
    private SwaggerEntity front;
    private SwaggerEntity back;

    @Data
    public static class SwaggerEntity{
        private String groupName;
        private String basePackege;
        private String title;
        private String description;
        private String contactName;
        private String contactEmail;
        private String contactUrl;
        private String version;
        private Boolean enable;
    }
}
           

全局配置類

spring:
  swagger3:
    front:
      enable: true
      groupName: 前端接口
      basePackege: com.example.demo.controller.api
      title: 前端測試接口
      description: 前端測試Spring Boot整合Swagger3.0
      contactName: nihui
      contactEmail: [email protected]
      contactUrl: https://blog.csdn.net/nihui123
      version: 0.0.1
    back:
      enable: true
      groupName: 後端接口
      basePackege: com.example.demo.controller.web
      title: 後端測試接口
      description: 後端測試Spring Boot整合Swagger3.0
      contactName: nihui
      contactEmail: [email protected]
      contactUrl: https://blog.csdn.net/nihui123
      version: 0.0.1
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher           

通過上面的配置完成配置之後,就會看到在接口頁面會有兩個分組,一個是前端接口、一個是後端接口分組。

Spring Boot 進階-詳解Spring Boot中使用Swagger3.0

添加授權認證資訊

在很多對外提供服務的API接口中,都會有一個授權認證的操作,否則這些接口是無法進行調用的。例如在一般的情況下,會在接口中包含一個TOKEN參數。

那麼在Swagger3.0中如何對這個認證資訊進行配置,這樣在每次請求的時候都會帶着這個參數進行請求,這樣就避免了我們在測試過程中,每次都需要添加這個資訊的麻煩。

要完成授權資訊的添加,我們需要在Docket方法中添加如下的内容

@Configuration
public class BaseSwagger3Config {

    @Autowired
    private BaseSwagger3Properties properties;

    @Bean
    public Docket baseApi(){
        return new Docket(DocumentationType.OAS_30)
                // 是否開啟,根據環境配置
                .enable(properties.getEnable())
                .groupName(properties.getGroupName())
                .apiInfo(frontApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage(properties.getBasePackege()))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

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

    private List<SecurityContext> securityContexts(){
        return Collections.singletonList(SecurityContext.builder().
                securityReferences(Collections.singletonList(
                        new SecurityReference("TOKEN",new AuthorizationScope[]
                                {new AuthorizationScope("global","")}))).build());
    }

    // 前台API資訊
    private ApiInfo frontApiInfo(){
        return new ApiInfoBuilder()
                .title(properties.getTitle())
                .description(properties.getDescription())
                .version(properties.getVersion())
                .contact(
                        // 添加開發者資訊
                        new Contact(
                                properties.getContactName(),
                                properties.getContactUrl(),
                                properties.getContactEmail())
                ).build();
    }

}
           

完成上述配置之後,會看到在接口頁面上會多出一個認證的按鈕。通過這個認證的按鈕我們可以設定對應的參數值

Spring Boot 進階-詳解Spring Boot中使用Swagger3.0

添加公共參數

在不同的平台使用的時候,除了攜帶請求Token之外還會有一些使用者進行使用者分析,大資料分析的參數被傳到請求中。那麼如何在Swagger3.0中去定義這些公共參數呢?這個時候我們需要在配置代碼中添加如下的内容。

@Configuration
public class BaseSwagger3Config {

    @Autowired
    private BaseSwagger3Properties properties;

    @Bean
    public Docket baseApi(){

        RequestParameter requestParameter = new RequestParameterBuilder()
                .name("clientType")
                .description("用戶端類型")
                .in(ParameterType.HEADER)
                .required(true)
                .build();

        //建立一個請求參數集合
        List<RequestParameter> requestParameterList = Collections.singletonList(requestParameter);


        return new Docket(DocumentationType.OAS_30)
                // 是否開啟,根據環境配置
                .enable(properties.getEnable())
                .groupName(properties.getGroupName())
                .apiInfo(frontApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage(properties.getBasePackege()))
                .paths(PathSelectors.any())
                .build()
                .globalRequestParameters(requestParameterList)
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

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

    private List<SecurityContext> securityContexts(){
        return Collections.singletonList(SecurityContext.builder().
                securityReferences(Collections.singletonList(
                        new SecurityReference("TOKEN",new AuthorizationScope[]
                                {new AuthorizationScope("global","")}))).build());
    }

    // 前台API資訊
    private ApiInfo frontApiInfo(){
        return new ApiInfoBuilder()
                .title(properties.getTitle())
                .description(properties.getDescription())
                .version(properties.getVersion())
                .contact(
                        // 添加開發者資訊
                        new Contact(
                                properties.getContactName(),
                                properties.getContactUrl(),
                                properties.getContactEmail())
                ).build();
    }

}
           

會看到上述代碼中通過,RequestParameter定義了一個公共的參數,并且将其放入到了一個參數集合中,通過Docket的.globalRequestParameters(requestParameterList)方法将其添加到Swagger3.0文檔中。然後運作項目會看到在接口中就會攜帶這對應的參數出現,并且這個參數是全局的,也就是說每個接口中都需要有這一個參數。

Spring Boot 進階-詳解Spring Boot中使用Swagger3.0

到這裡,Swagger的相關内容就告一段落了。細心的讀者會發現,在前面我們添加分組配置的時候在配置類上添加了好多的注解,但是在我們示範認證資訊與全局參數的時候,配置類中隻是簡單的添加了一個@Configuration 注解。這是為什麼呢?下面我們就來探索一下源碼。

OpenApiAutoConfiguration 源碼

會看到在這段源碼中,好像什麼功能都沒實作,但是它确完成了Swagger3.0大多數的配置,而對于@EnableOpenApi 注解來講。

@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.class, JacksonAutoConfiguration.class,
    HttpMessageConvertersAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class })
public class OpenApiAutoConfiguration {

}
           

@EnableOpenApi 注解

對于@EnableOpenApi注解來講其關鍵的代碼就是@Import(OpenApiDocumentationConfiguration.class) 引入的還是這個類。

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = {java.lang.annotation.ElementType.TYPE})
@Documented
@Import(OpenApiDocumentationConfiguration.class)
public @interface EnableOpenApi {
}
           

這裡我們會發現為什麼在沒有@EnableOpenApi注解的時候也會生效呢?那就是用到了我們Spring Boot自動配置的原理了。關于自動配置的原理在後續的分析中我們來進行講解,這裡就先不做過多說明。提示大家的就是找到如下圖中的代碼就可以了解自動配置的原理

Spring Boot 進階-詳解Spring Boot中使用Swagger3.0

總結

通過上面的内容我們了解了Swagger3.0的一些擴充性的用法,當然Swagger的用法遠遠不止這些,但是這些内容已經可以支援在我們日常開發中的一些工作。希望大家多多關注,筆者會為大家帶來更多精彩幹活

繼續閱讀