hanqingsong 1 anno fa
parent
commit
e87114db31

+ 9 - 0
README.md

@@ -0,0 +1,9 @@
1
+# swagger 集成 2.9.2
2
+## spring boot 2.7.15 cloud 2021.0.8
3
+
4
+# swagger document
5
+## get yaml for /resources/openapi-config.yaml
6
+### 示例:http://localhost:8082/v3/api-docs
7
+
8
+# swagger接口地址
9
+## http://localhost:8082/doc.html#/home

+ 34 - 0
pom.xml

@@ -21,6 +21,8 @@
21 21
         <mybatisPlus.version>3.4.1</mybatisPlus.version>
22 22
         <mybatis.version>2.1.4</mybatis.version>
23 23
         <fastjson.version>1.2.83</fastjson.version>
24
+        <springdoc.version>1.6.14</springdoc.version>
25
+        <knife4j.version>4.0.0</knife4j.version>
24 26
     </properties>
25 27
     <dependencies>
26 28
         <!-- 达梦数据库驱动 -->
@@ -54,6 +56,38 @@
54 56
             <groupId>org.projectlombok</groupId>
55 57
             <artifactId>lombok</artifactId>
56 58
         </dependency>
59
+        <!-- swagger -->
60
+        <dependency>
61
+            <groupId>org.springdoc</groupId>
62
+            <artifactId>springdoc-openapi-webmvc-core</artifactId>
63
+            <version>1.6.9</version>
64
+        </dependency>
65
+        <!--<dependency>
66
+            <groupId>org.springdoc</groupId>
67
+            <artifactId>springdoc-openapi-security</artifactId>
68
+            <version>1.6.9</version>
69
+        </dependency>-->
70
+        <dependency>
71
+            <groupId>io.swagger.core.v3</groupId>
72
+            <artifactId>swagger-annotations</artifactId>
73
+            <version>2.2.0</version>
74
+        </dependency>
75
+        <dependency>
76
+            <groupId>org.springframework.cloud</groupId>
77
+            <artifactId>spring-cloud-commons</artifactId>
78
+            <scope>provided</scope>
79
+        </dependency>
80
+        <dependency>
81
+            <groupId>org.springdoc</groupId>
82
+            <artifactId>springdoc-openapi-ui</artifactId>
83
+            <version>${springdoc.version}</version>
84
+        </dependency>
85
+        <dependency>
86
+            <groupId>com.github.xiaoymin</groupId>
87
+            <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
88
+            <version>${knife4j.version}</version>
89
+        </dependency>
90
+        <!-- end -->
57 91
         <dependency>
58 92
             <groupId>org.springframework.boot</groupId>
59 93
             <artifactId>spring-boot-starter-web</artifactId>

+ 2 - 0
src/main/java/com/unis/VsualizationReportApplication.java

@@ -1,9 +1,11 @@
1 1
 package com.unis;
2 2
 
3
+import com.unis.common.swagger.annotation.EnableOpenApi;
3 4
 import org.mybatis.spring.annotation.MapperScan;
4 5
 import org.springframework.boot.SpringApplication;
5 6
 import org.springframework.boot.autoconfigure.SpringBootApplication;
6 7
 
8
+@EnableOpenApi(value = "admin", isMicro = false)
7 9
 @SpringBootApplication
8 10
 @MapperScan({
9 11
         "com.unis.*.mapper"

+ 44 - 0
src/main/java/com/unis/common/factory/YamlPropertySourceFactory.java

@@ -0,0 +1,44 @@
1
+package com.unis.common.factory;
2
+
3
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
4
+import org.springframework.core.env.PropertiesPropertySource;
5
+import org.springframework.core.env.PropertySource;
6
+import org.springframework.core.io.support.EncodedResource;
7
+import org.springframework.core.io.support.PropertySourceFactory;
8
+import org.springframework.lang.Nullable;
9
+
10
+import java.io.FileNotFoundException;
11
+import java.io.IOException;
12
+import java.util.Properties;
13
+
14
+/**
15
+ * @author avenue
16
+ * @date 2022/3/29
17
+ * <p>
18
+ * 读取自定义 yaml 文件工厂类
19
+ */
20
+public class YamlPropertySourceFactory implements PropertySourceFactory {
21
+
22
+    @Override
23
+    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
24
+        Properties propertiesFromYaml = loadYamlIntoProperties(resource);
25
+        String sourceName = name != null ? name : resource.getResource().getFilename();
26
+        return new PropertiesPropertySource(sourceName, propertiesFromYaml);
27
+    }
28
+
29
+    private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
30
+        try {
31
+            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
32
+            factory.setResources(resource.getResource());
33
+            factory.afterPropertiesSet();
34
+            return factory.getObject();
35
+        }
36
+        catch (IllegalStateException e) {
37
+            Throwable cause = e.getCause();
38
+            if (cause instanceof FileNotFoundException)
39
+                throw (FileNotFoundException) e.getCause();
40
+            throw e;
41
+        }
42
+    }
43
+
44
+}

+ 55 - 0
src/main/java/com/unis/common/swagger/annotation/EnableOpenApi.java

@@ -0,0 +1,55 @@
1
+/*
2
+ * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+package com.unis.common.swagger.annotation;
18
+
19
+import com.unis.common.factory.YamlPropertySourceFactory;
20
+import com.unis.common.swagger.config.OpenAPIDefinitionImportSelector;
21
+import com.unis.common.swagger.support.SwaggerProperties;
22
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
23
+import org.springframework.context.annotation.Import;
24
+import org.springframework.context.annotation.PropertySource;
25
+
26
+import java.lang.annotation.*;
27
+
28
+/**
29
+ * 开启 pig spring doc
30
+ *
31
+ * @author avenue
32
+ * @date 2022-03-26
33
+ */
34
+@Target({ ElementType.TYPE })
35
+@Retention(RetentionPolicy.RUNTIME)
36
+@Documented
37
+@Inherited
38
+@EnableConfigurationProperties(SwaggerProperties.class)
39
+@Import({ OpenAPIDefinitionImportSelector.class })
40
+@PropertySource(value = "classpath:openapi-config.yaml", factory = YamlPropertySourceFactory.class)
41
+public @interface EnableOpenApi {
42
+
43
+    /**
44
+     * 网关路由前缀
45
+     * @return String
46
+     */
47
+    String value() default "";
48
+
49
+    /**
50
+     * 是否是微服务架构
51
+     * @return true
52
+     */
53
+    boolean isMicro() default true;
54
+
55
+}

+ 90 - 0
src/main/java/com/unis/common/swagger/config/OpenAPIDefinition.java

@@ -0,0 +1,90 @@
1
+/*
2
+ *    Copyright (c) 2018-2025, avenue All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are met:
6
+ *
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ * this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright
10
+ * notice, this list of conditions and the following disclaimer in the
11
+ * documentation and/or other materials provided with the distribution.
12
+ * Neither the name of the pig4cloud.com developer nor the names of its
13
+ * contributors may be used to endorse or promote products derived from
14
+ * this software without specific prior written permission.
15
+ * Author: avenue
16
+ */
17
+package com.unis.common.swagger.config;
18
+
19
+import com.unis.common.swagger.support.SwaggerProperties;
20
+import io.swagger.v3.oas.models.OpenAPI;
21
+import io.swagger.v3.oas.models.info.Info;
22
+import io.swagger.v3.oas.models.security.OAuthFlow;
23
+import io.swagger.v3.oas.models.security.OAuthFlows;
24
+import io.swagger.v3.oas.models.security.Scopes;
25
+import io.swagger.v3.oas.models.security.SecurityScheme;
26
+import io.swagger.v3.oas.models.servers.Server;
27
+import lombok.RequiredArgsConstructor;
28
+import lombok.Setter;
29
+import org.springframework.beans.BeansException;
30
+import org.springframework.beans.factory.InitializingBean;
31
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
32
+import org.springframework.context.ApplicationContext;
33
+import org.springframework.context.ApplicationContextAware;
34
+import org.springframework.http.HttpHeaders;
35
+
36
+import java.util.ArrayList;
37
+import java.util.List;
38
+
39
+/**
40
+ * swagger配置
41
+ *
42
+ * <p>
43
+ * 禁用方法1:使用注解@Profile({"dev","test"})
44
+ *
45
+ * 表示在开发或测试环境开启,而在生产关闭。(推荐使用) 禁用方法2:使用注解@ConditionalOnProperty(name = "swagger.enable",
46
+ *
47
+ * havingValue = "true") 然后在测试配置或者开发配置中添加swagger.enable=true即可开启,生产环境不填则默认关闭Swagger.
48
+ * </p>
49
+ *
50
+ * @author avenue
51
+ */
52
+@RequiredArgsConstructor
53
+@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
54
+public class OpenAPIDefinition extends OpenAPI implements InitializingBean, ApplicationContextAware {
55
+
56
+    @Setter
57
+    private String path;
58
+
59
+    private ApplicationContext applicationContext;
60
+
61
+    private SecurityScheme securityScheme(SwaggerProperties swaggerProperties) {
62
+        OAuthFlow clientCredential = new OAuthFlow();
63
+        clientCredential.setTokenUrl(swaggerProperties.getTokenUrl());
64
+        clientCredential.setScopes(new Scopes().addString(swaggerProperties.getScope(), swaggerProperties.getScope()));
65
+        OAuthFlows oauthFlows = new OAuthFlows();
66
+        oauthFlows.password(clientCredential);
67
+        SecurityScheme securityScheme = new SecurityScheme();
68
+        securityScheme.setType(SecurityScheme.Type.OAUTH2);
69
+        securityScheme.setFlows(oauthFlows);
70
+        return securityScheme;
71
+    }
72
+
73
+    @Override
74
+    public void afterPropertiesSet() throws Exception {
75
+        SwaggerProperties swaggerProperties = applicationContext.getBean(SwaggerProperties.class);
76
+        this.info(new Info().title(swaggerProperties.getTitle()));
77
+        // oauth2.0 password
78
+        this.schemaRequirement(HttpHeaders.AUTHORIZATION, this.securityScheme(swaggerProperties));
79
+        // servers
80
+        List<Server> serverList = new ArrayList<>();
81
+        serverList.add(new Server().url(swaggerProperties.getGateway() + "/" + path));
82
+        this.servers(serverList);
83
+    }
84
+
85
+    @Override
86
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
87
+        this.applicationContext = applicationContext;
88
+    }
89
+
90
+}

+ 47 - 0
src/main/java/com/unis/common/swagger/config/OpenAPIDefinitionImportSelector.java

@@ -0,0 +1,47 @@
1
+package com.unis.common.swagger.config;
2
+
3
+import com.unis.common.swagger.annotation.EnableOpenApi;
4
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
5
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
6
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
7
+import org.springframework.core.type.AnnotationMetadata;
8
+
9
+import java.util.Map;
10
+import java.util.Objects;
11
+
12
+/**
13
+ * openapi 配置类
14
+ *
15
+ * @author avenue
16
+ * @date 2023/1/1
17
+ */
18
+public class OpenAPIDefinitionImportSelector implements ImportBeanDefinitionRegistrar {
19
+
20
+    @Override
21
+    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
22
+
23
+        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(EnableOpenApi.class.getName(),
24
+                true);
25
+        Object value = annotationAttributes.get("value");
26
+        if (Objects.isNull(value)) {
27
+            return;
28
+        }
29
+
30
+        BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(OpenAPIDefinition.class);
31
+        definition.addPropertyValue("path", value);
32
+
33
+        registry.registerBeanDefinition("openAPIDefinition", definition.getBeanDefinition());
34
+
35
+        // 如果是微服务架构则,引入了服务发现声明相关的元数据配置
36
+        Object isMicro = annotationAttributes.getOrDefault("isMicro", true);
37
+        if (isMicro.equals(false)) {
38
+            return;
39
+        }
40
+
41
+        BeanDefinitionBuilder openAPIMetadata = BeanDefinitionBuilder
42
+                .genericBeanDefinition(OpenAPIMetadataConfiguration.class);
43
+        openAPIMetadata.addPropertyValue("path", value);
44
+        registry.registerBeanDefinition("openAPIMetadata", openAPIMetadata.getBeanDefinition());
45
+    }
46
+
47
+}

+ 32 - 0
src/main/java/com/unis/common/swagger/config/OpenAPIMetadataConfiguration.java

@@ -0,0 +1,32 @@
1
+package com.unis.common.swagger.config;
2
+
3
+import lombok.Setter;
4
+import org.springframework.beans.BeansException;
5
+import org.springframework.beans.factory.InitializingBean;
6
+import org.springframework.cloud.client.ServiceInstance;
7
+import org.springframework.context.ApplicationContext;
8
+import org.springframework.context.ApplicationContextAware;
9
+
10
+/**
11
+ * @author avenue
12
+ * @date 2023/1/4
13
+ */
14
+public class OpenAPIMetadataConfiguration implements InitializingBean, ApplicationContextAware {
15
+
16
+    private ApplicationContext applicationContext;
17
+
18
+    @Setter
19
+    private String path;
20
+
21
+    @Override
22
+    public void afterPropertiesSet() throws Exception {
23
+        ServiceInstance serviceInstance = applicationContext.getBean(ServiceInstance.class);
24
+        serviceInstance.getMetadata().put("spring-doc", path);
25
+    }
26
+
27
+    @Override
28
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
29
+        this.applicationContext = applicationContext;
30
+    }
31
+
32
+}

+ 86 - 0
src/main/java/com/unis/common/swagger/support/SwaggerProperties.java

@@ -0,0 +1,86 @@
1
+/*
2
+ *    Copyright (c) 2018-2025, avenue All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are met:
6
+ *
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ * this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright
10
+ * notice, this list of conditions and the following disclaimer in the
11
+ * documentation and/or other materials provided with the distribution.
12
+ * Neither the name of the pig4cloud.com developer nor the names of its
13
+ * contributors may be used to endorse or promote products derived from
14
+ * this software without specific prior written permission.
15
+ * Author: avenue
16
+ */
17
+package com.unis.common.swagger.support;
18
+
19
+import lombok.Data;
20
+import org.springframework.boot.context.properties.ConfigurationProperties;
21
+
22
+import java.util.ArrayList;
23
+import java.util.List;
24
+import java.util.Map;
25
+
26
+/**
27
+ * SwaggerProperties
28
+ *
29
+ * @author avenue
30
+ * @date 2018/7/25 14:00
31
+ */
32
+@Data
33
+@ConfigurationProperties("swagger")
34
+public class SwaggerProperties {
35
+
36
+    /**
37
+     * 是否开启swagger
38
+     */
39
+    private Boolean enabled = true;
40
+
41
+    /**
42
+     * swagger会解析的包路径
43
+     **/
44
+    private String basePackage = "";
45
+
46
+    /**
47
+     * swagger会解析的url规则
48
+     **/
49
+    private List<String> basePath = new ArrayList<>();
50
+
51
+    /**
52
+     * 在basePath基础上需要排除的url规则
53
+     **/
54
+    private List<String> excludePath = new ArrayList<>();
55
+
56
+    /**
57
+     * 需要排除的服务
58
+     */
59
+    private List<String> ignoreProviders = new ArrayList<>();
60
+
61
+    /**
62
+     * 标题
63
+     **/
64
+    private String title = "";
65
+
66
+    /**
67
+     * 网关
68
+     */
69
+    private String gateway;
70
+
71
+    /**
72
+     * 获取token
73
+     */
74
+    private String tokenUrl;
75
+
76
+    /**
77
+     * 作用域
78
+     */
79
+    private String scope;
80
+
81
+    /**
82
+     * 服务转发配置
83
+     */
84
+    private Map<String, String> services;
85
+
86
+}

+ 20 - 1
src/main/resources/application.yml

@@ -1,5 +1,7 @@
1 1
 server:
2 2
   port: 8082
3
+  servlet:
4
+    context-path: /
3 5
   tomcat:
4 6
     uri-encoding: UTF-8
5 7
 spring:
@@ -49,4 +51,21 @@ mybatis-plus:
49 51
   configuration:
50 52
     call-setters-on-nulls: true
51 53
     # console show sql
52
-    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
54
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
55
+## spring security 配置
56
+security:
57
+  oauth2:
58
+    client:
59
+      client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)
60
+      client-secret: ENC(ltJPpR50wT0oIY9kfOe1Iw==)
61
+      scope: server
62
+      ignore-urls:
63
+        - /webjars/**
64
+        - /v3/api-docs/**
65
+        - /doc.html
66
+        - /swagger-resources
67
+        - /css/**
68
+        - /error
69
+        - /druid/**
70
+        - /actuator/**
71
+        - /code/**

+ 7 - 0
src/main/resources/openapi-config.yaml

@@ -0,0 +1,7 @@
1
+# swagger 配置
2
+swagger:
3
+  enabled: true
4
+  title: avenue Swagger API
5
+  gateway: http://${GATEWAY-HOST:avenue-gateway}:${GATEWAY-PORT:9999}
6
+  token-url: ${swagger.gateway}/auth/oauth2/token
7
+  scope: server