天天看點

微服務實戰(七) 聚合OpenAPI文檔

微服務實戰(六) 基于 Knife4jAggregationDesktop實作聚合OpenAPI文檔

官方文檔:https://doc.xiaominfo.com/knife4j/resources/aggregation-introduction.html

  • swagger-bootstrap-ui

    springfox-swagger

    的增強UI實作,為Java開發者在使用Swagger的時候,能擁有一份簡潔、強大的接口文檔體驗
  • Knife4j

    是為Java MVC架構內建Swagger生成Api文檔的增強解決方案,前身是

    swagger-bootstrap-ui

    ,取名kni4j是希望她能像一把匕首一樣小巧,輕量,并且功能強悍!
  • Knife4jAggregation

    是給Spring Boot的web系統賦能,擁有聚合OpenAPI文檔的能力
  • Knife4jAggregationDesktop

    是一款基于聚合元件

    Knife4jAggregation

    特性的獨立部署的聚合OpenAPI文檔軟體,脫離Spring、Spring Boot技術架構體系,開發者下載下傳後獨立部署啟動。開發者可以了解為能夠渲染OpenAPI規範的獨立文檔應用

自定義swagger子產品

子產品結構

├─src
│  └─main
│      ├─java
│      │  └─com.sunnyws.common.swagger
│      │             ├── annotation
│      │             │      └── EnableKnife4jSwagger.java
│      │             └── config
│      │                     ├── SwaggerAutoConfiguration.java
│      │                     └── SwaggerProperties.java
│      └─resources
           

引入依賴

  • 引入

    knife4j-spring-boot-starter

    swagger-models``knife4j-micro-spring-boot-starter

  • 引入

    knife4j-spring-boot-starter

    則每個項目都有單獨的swagger文檔,不影響Knife4jAggregationDesktop進行聚合使用
  • 引入

    swagger-models``knife4j-micro-spring-boot-starter

    隻是剔除了

    knife4j-spring-boot-starter

    的前端部分,每個項目無法通過頁面單獨檢視swagger文檔,隻能通過Knife4jAggregationDesktop聚合檢視
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>
           

<dependency>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-models</artifactId>
    <version>1.5.22</version>
</dependency>

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

完整依賴

<properties>
        <knife4j.swagger.version>3.0.2</knife4j.swagger.version>
        <swagger.version>1.5.22</swagger.version>
    </properties>


    <dependencies>
        <!-- SpringBoot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>com.github.xiaoymin</groupId>-->
<!--            <artifactId>knife4j-spring-boot-starter</artifactId>-->
<!--            <version>${knife4j.swagger.version}</version>-->
<!--        </dependency>-->
        
        <!-- knife4j swagger -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-micro-spring-boot-starter</artifactId>
            <version>${knife4j.swagger.version}</version>
        </dependency>
    </dependencies>
           

自定義swagger配置

  • 除了通過自定義屬性,對swagger必要參數進行設定,也可以通過knife4j增強特性對knife4j swagger前端頁面一些參數進行修改,這裡就不詳細說,可以通過官方文檔學習。
  • 官方文檔:https://doc.xiaominfo.com/knife4j/documentation/
@Data
@Component
@ConfigurationProperties("swagger")
public class SwaggerProperties {
    /**
     * 是否開啟swagger
     */
    private Boolean enabled = true;

    /**
     * swagger會解析的包路徑
     **/
    private String basePackage = "";


    /**
     * group
     **/
    private String groupName = "default";

    /**
     * swagger會解析的url規則
     **/
    private List<String> basePath = new ArrayList<>();

    /**
     * 在basePath基礎上需要排除的url規則
     **/
    private List<String> excludePath = new ArrayList<>();

    /**
     * 标題
     **/
    private String title = "swagger";

    /**
     * 描述
     **/
    private String description = "swagger document";

    /**
     * 版本
     **/
    private String version = "1.0";

    /**
     * 許可證
     **/
    private String license = "";

    /**
     * 許可證URL
     **/
    private String licenseUrl = "";

    /**
     * 服務條款URL
     **/
    private String termsOfServiceUrl = "";

    /**
     * host資訊
     **/
    private String host = "";

    /**
     * 聯系人資訊
     */
    private Contact contact = new Contact();


    @Data
    public static class Contact {
        /**
         * 聯系人
         **/
        private String name = "";
        /**
         * 聯系人url
         **/
        private String url = "";
        /**
         * 聯系人email
         **/
        private String email = "";

    }

}
           
@EnableSwagger2
@EnableAutoConfiguration
public class SwaggerAutoConfiguration {
    /**
     * 預設的排除路徑,排除Spring Boot預設的錯誤處理路徑和端點
     */
    private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");

    private static final String BASE_PATH = "/**";

    @Bean
    public SwaggerProperties swaggerProperties()
    {
        return new SwaggerProperties();
    }

    @Bean
    @Order(value = 1)
    public Docket api(SwaggerProperties swaggerProperties) {
        // base-path處理
        if (swaggerProperties.getBasePath().isEmpty()) {
            swaggerProperties.getBasePath().add(BASE_PATH);
        }

        return new Docket(DocumentationType.SWAGGER_2)
                .enable(swaggerProperties.getEnabled())
                .host(swaggerProperties.getHost())
                .apiInfo(apiInfo(swaggerProperties)).select()
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
                .paths(PathSelectors.any())
                .build()
                .groupName(swaggerProperties.getGroupName())
                .securityContexts(CollectionUtils.newArrayList(securityContext(),securityContext1()))
                .securitySchemes(CollectionUtils.<SecurityScheme>newArrayList(apiKey(),apiKey1()));
    }

    private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
        return new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .license(swaggerProperties.getLicense())
                .licenseUrl(swaggerProperties.getLicenseUrl())
                .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
                .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
                .version(swaggerProperties.getVersion())
                .build();
    }

    /**
     * 安全模式,這裡指定token通過Authorization頭請求頭傳遞
     */
    private ApiKey apiKey() {
        return new ApiKey("BearerToken", "Authorization", "header");
    }
    private ApiKey apiKey1() {
        return new ApiKey("BearerToken1", "Authorization-x", "header");
    }

    /**
     * 安全上下文
     */
    private SecurityContext securityContext() {
        return SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("/.*"))
                .build();
    }
    private SecurityContext securityContext1() {
        return SecurityContext.builder()
                .securityReferences(defaultAuth1())
                .forPaths(PathSelectors.regex("/.*"))
                .build();
    }
    /**
     * 預設的全局鑒權政策
     *
     * @return
     */
    List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return CollectionUtils.newArrayList(new SecurityReference("BearerToken", authorizationScopes));
    }
    List<SecurityReference> defaultAuth1() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return CollectionUtils.newArrayList(new SecurityReference("BearerToken1", authorizationScopes));
    }

}

           

自定義注解

@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({ SwaggerAutoConfiguration.class })
public @interface EnableKnife4jSwagger {

}
           

引用Swagger

引入依賴

  • 版本根據自己的項目定義
  • 使用Nacos注冊中心,以便Knife4jAggregationDesktop+Nacos實作聚合
<dependency>
    <groupId>sunnyws.com</groupId>
    <artifactId>sunnyws-common-swagger</artifactId>
</dependency>
<!-- SpringCloud Ailibaba Nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
           

添加配置

詳細配置檢視自定義的

SwaggerProperties.java

server:
  port: 9001
spring:
  application:
    name: sunnyws-service-example1
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: 172.16.220.50:8848
        namespace: e90d261b-9c05-4bcb-b99f-b419d952737a

swagger:
  enabled: true
  basePackage: com.sunnyws.example1.controller
  title: example1 swagger
  description: <div style='font-size:14px;color:red;'>swagger-bootstrap-ui-demo RESTful APIs</div>
  version: 1.0
  termsOfServiceUrl: test.cn
  groupName: default
  contact:
    name:  test
    url:   test.cn
    email: [email protected]

           

啟動類添加注解

@SpringBootApplication
@EnableDiscoveryClient
@EnableKnife4jSwagger
public class ServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }
}
           

Knife4jAggregationDesktop

  • 官方提供了四種方式聚合,這裡隻是簡單使用Nacos,其他請看官方文檔
  • 第一篇 Knife4jAggregationDesktop介紹(opens new window)
  • 第二篇 Knige4jAggregationDesktiop安裝和使用說明(opens new window)
  • 第三篇 Knife4jAggregationDesktop使用-Disk模式(opens new window)
  • 第四篇 Knife4jAggregationDesktop使用-Cloud模式(opens new window)
  • 第五篇 Knife4jAggregationDesktop使用-Eureka模式(opens new window)
  • 第六篇 Knife4jAggregationDesktop使用-Nacos模式(opens new window)

安裝

  • 下載下傳位址:https://gitee.com/xiaoym/knife4j/attach_files

Linux環境

#bin目錄下的startup.sh檔案賦予可執行權限
chmod a+x startup.sh

#啟動
./sh startup.sh
           

修改配置

#進入data下ROOT目錄下添加配置,當然也可根據官方文檔 在ROOT外建立配置目錄 進行配置
cd  ./data/ROOT
#删除初始disk配置示例
rm ./*
#建立Nacos模式配置
touch  nacos.properties
#修改配置
vim  ./nacos.properties


#根據Nacos配置和服務名  修改添加如下配置
knife4j.nacos.serviceUrl=http://172.16.220.50:8848/nacos/
knife4j.nacos.routes[0].name=測試一
knife4j.nacos.routes[0].serviceName=sunnyws-service-example1
knife4j.nacos.routes[0].location=/v2/api-docs?group=default
knife4j.nacos.routes[0].namespaceId:e90d261b-9c05-4bcb-b99f-b419d952737a
knife4j.nacos.routes[1].name=測試二 
knife4j.nacos.routes[1].serviceName=sunnyws-service-example2
knife4j.nacos.routes[1].location=/v2/api-docs?group=default
knife4j.nacos.routes[1].namespaceId:e90d261b-9c05-4bcb-b99f-b419d952737a
#開啟認證
#knife4j.basicAuth.enable=true
#knife4j.basicAuth.username=nacos
#knife4j.basicAuth.password=1234
           

通路頁面

  • 預設端口:18006
  • 網址:http://ip:18006/doc.html
微服務實戰(七) 聚合OpenAPI文檔

作者: SunnyWs

連結: https://sunnyws.com/posts/ec81c193/

來源: SunnyWs’Blog

繼續閱讀