From 3b5164cf55f9904cd709d0b24d9b92c9423879b2 Mon Sep 17 00:00:00 2001
From: fst1996 <2411194573@qq.com>
Date: Sat, 18 Nov 2023 14:45:28 +0800
Subject: [PATCH] =?UTF-8?q?god-common-swagger=E5=88=9D=E5=A7=8B=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 46 +++
pom.xml | 51 +++
.../annotation/EnableCustomSwagger2.java | 15 +
.../config/SwaggerAutoConfiguration.java | 111 +++++++
.../config/SwaggerBeanPostProcessor.java | 45 +++
.../swagger/config/SwaggerProperties.java | 296 ++++++++++++++++++
.../config/SwaggerWebConfiguration.java | 18 ++
...ot.autoconfigure.AutoConfiguration.imports | 3 +
8 files changed, 585 insertions(+)
create mode 100644 .gitignore
create mode 100644 pom.xml
create mode 100644 src/main/java/com/god/common/swagger/annotation/EnableCustomSwagger2.java
create mode 100644 src/main/java/com/god/common/swagger/config/SwaggerAutoConfiguration.java
create mode 100644 src/main/java/com/god/common/swagger/config/SwaggerBeanPostProcessor.java
create mode 100644 src/main/java/com/god/common/swagger/config/SwaggerProperties.java
create mode 100644 src/main/java/com/god/common/swagger/config/SwaggerWebConfiguration.java
create mode 100644 src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..09bdfea
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,46 @@
+######################################################################
+# Build Tools
+
+.gradle
+/build/
+!gradle/wrapper/gradle-wrapper.jar
+
+target/
+!.mvn/wrapper/maven-wrapper.jar
+
+######################################################################
+# IDE
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### JRebel ###
+rebel.xml
+### NetBeans ###
+nbproject/private/
+build/*
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+######################################################################
+# Others
+*.log
+*.xml.versionsBackup
+*.swp
+
+!*/build/*.java
+!*/build/*.html
+!*/build/*.xml
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ac73e91
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,51 @@
+
+
+
+ com.god
+ god-common
+ 3.6.3
+
+ 4.0.0
+
+ god-common-swagger
+ 3.6.3
+
+
+ god-common-swagger系统接口
+
+
+
+
+ menghang-public
+ 梦航-public
+ http://10.100.1.6:8081/repository/maven-public/
+
+
+
+
+
+ menghang-releases
+ 梦航-releases
+ http://10.100.1.6:8081/repository/maven-releases/
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${swagger.fox.version}
+
+
+
+
diff --git a/src/main/java/com/god/common/swagger/annotation/EnableCustomSwagger2.java b/src/main/java/com/god/common/swagger/annotation/EnableCustomSwagger2.java
new file mode 100644
index 0000000..78d1319
--- /dev/null
+++ b/src/main/java/com/god/common/swagger/annotation/EnableCustomSwagger2.java
@@ -0,0 +1,15 @@
+package com.god.common.swagger.annotation;
+
+import com.god.common.swagger.config.SwaggerAutoConfiguration;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import({SwaggerAutoConfiguration.class})
+public @interface EnableCustomSwagger2 {
+
+}
diff --git a/src/main/java/com/god/common/swagger/config/SwaggerAutoConfiguration.java b/src/main/java/com/god/common/swagger/config/SwaggerAutoConfiguration.java
new file mode 100644
index 0000000..d6d6eb1
--- /dev/null
+++ b/src/main/java/com/god/common/swagger/config/SwaggerAutoConfiguration.java
@@ -0,0 +1,111 @@
+package com.god.common.swagger.config;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.*;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+
+@Configuration
+@EnableSwagger2
+@EnableConfigurationProperties(SwaggerProperties.class)
+@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
+@Import({SwaggerBeanPostProcessor.class, SwaggerWebConfiguration.class})
+public class SwaggerAutoConfiguration {
+ /**
+ * 默认的排除路径,排除Spring Boot默认的错误处理路径和端点
+ */
+ private static final List DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
+
+ private static final String BASE_PATH = "/**";
+
+ @Bean
+ public Docket api (SwaggerProperties swaggerProperties) {
+ // base-path处理
+ if (swaggerProperties.getBasePath().isEmpty()) {
+ swaggerProperties.getBasePath().add(BASE_PATH);
+ }
+ // noinspection unchecked
+ List> basePath = new ArrayList>();
+ swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path)));
+
+ // exclude-path处理
+ if (swaggerProperties.getExcludePath().isEmpty()) {
+ swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
+ }
+
+ List> excludePath = new ArrayList<>();
+ swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
+
+ ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost())
+ .apiInfo(apiInfo(swaggerProperties)).select()
+ .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
+
+ swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
+ swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
+
+ return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/");
+ }
+
+ /**
+ * 安全模式,这里指定token通过Authorization头请求头传递
+ */
+ private List securitySchemes () {
+ List apiKeyList = new ArrayList();
+ apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
+ return apiKeyList;
+ }
+
+ /**
+ * 安全上下文
+ */
+ private List securityContexts () {
+ List securityContexts = new ArrayList<>();
+ securityContexts.add(
+ SecurityContext.builder()
+ .securityReferences(defaultAuth())
+ .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
+ .build());
+ return securityContexts;
+ }
+
+ /**
+ * 默认的全局鉴权策略
+ *
+ * @return
+ */
+ private List defaultAuth () {
+ AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+ AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+ authorizationScopes[0] = authorizationScope;
+ List securityReferences = new ArrayList<>();
+ securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
+ return securityReferences;
+ }
+
+ 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();
+ }
+}
diff --git a/src/main/java/com/god/common/swagger/config/SwaggerBeanPostProcessor.java b/src/main/java/com/god/common/swagger/config/SwaggerBeanPostProcessor.java
new file mode 100644
index 0000000..0f968f4
--- /dev/null
+++ b/src/main/java/com/god/common/swagger/config/SwaggerBeanPostProcessor.java
@@ -0,0 +1,45 @@
+package com.god.common.swagger.config;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
+import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
+import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * swagger 在 springboot 2.6.x 不兼容问题的处理
+ *
+ * @author god
+ */
+public class SwaggerBeanPostProcessor implements BeanPostProcessor {
+ @Override
+ public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException {
+ if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
+ customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
+ }
+ return bean;
+ }
+
+ private void customizeSpringfoxHandlerMappings (List mappings) {
+ List copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null)
+ .collect(Collectors.toList());
+ mappings.clear();
+ mappings.addAll(copy);
+ }
+
+ @SuppressWarnings("unchecked")
+ private List getHandlerMappings (Object bean) {
+ try {
+ Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
+ field.setAccessible(true);
+ return (List) field.get(bean);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
diff --git a/src/main/java/com/god/common/swagger/config/SwaggerProperties.java b/src/main/java/com/god/common/swagger/config/SwaggerProperties.java
new file mode 100644
index 0000000..2a49040
--- /dev/null
+++ b/src/main/java/com/god/common/swagger/config/SwaggerProperties.java
@@ -0,0 +1,296 @@
+package com.god.common.swagger.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@ConfigurationProperties("swagger")
+public class SwaggerProperties {
+ /**
+ * 是否开启swagger
+ */
+ private Boolean enabled;
+
+ /**
+ * swagger会解析的包路径
+ **/
+ private String basePackage = "";
+
+ /**
+ * swagger会解析的url规则
+ **/
+ private List basePath = new ArrayList<>();
+
+ /**
+ * 在basePath基础上需要排除的url规则
+ **/
+ private List excludePath = new ArrayList<>();
+
+ /**
+ * 标题
+ **/
+ private String title = "";
+
+ /**
+ * 描述
+ **/
+ private String description = "";
+
+ /**
+ * 版本
+ **/
+ private String version = "";
+
+ /**
+ * 许可证
+ **/
+ private String license = "";
+
+ /**
+ * 许可证URL
+ **/
+ private String licenseUrl = "";
+
+ /**
+ * 服务条款URL
+ **/
+ private String termsOfServiceUrl = "";
+
+ /**
+ * host信息
+ **/
+ private String host = "";
+
+ /**
+ * 联系人信息
+ */
+ private Contact contact = new Contact();
+
+ /**
+ * 全局统一鉴权配置
+ **/
+ private Authorization authorization = new Authorization();
+
+ public Boolean getEnabled () {
+ return enabled;
+ }
+
+ public void setEnabled (Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getBasePackage () {
+ return basePackage;
+ }
+
+ public void setBasePackage (String basePackage) {
+ this.basePackage = basePackage;
+ }
+
+ public List getBasePath () {
+ return basePath;
+ }
+
+ public void setBasePath (List basePath) {
+ this.basePath = basePath;
+ }
+
+ public List getExcludePath () {
+ return excludePath;
+ }
+
+ public void setExcludePath (List excludePath) {
+ this.excludePath = excludePath;
+ }
+
+ public String getTitle () {
+ return title;
+ }
+
+ public void setTitle (String title) {
+ this.title = title;
+ }
+
+ public String getDescription () {
+ return description;
+ }
+
+ public void setDescription (String description) {
+ this.description = description;
+ }
+
+ public String getVersion () {
+ return version;
+ }
+
+ public void setVersion (String version) {
+ this.version = version;
+ }
+
+ public String getLicense () {
+ return license;
+ }
+
+ public void setLicense (String license) {
+ this.license = license;
+ }
+
+ public String getLicenseUrl () {
+ return licenseUrl;
+ }
+
+ public void setLicenseUrl (String licenseUrl) {
+ this.licenseUrl = licenseUrl;
+ }
+
+ public String getTermsOfServiceUrl () {
+ return termsOfServiceUrl;
+ }
+
+ public void setTermsOfServiceUrl (String termsOfServiceUrl) {
+ this.termsOfServiceUrl = termsOfServiceUrl;
+ }
+
+ public String getHost () {
+ return host;
+ }
+
+ public void setHost (String host) {
+ this.host = host;
+ }
+
+ public Contact getContact () {
+ return contact;
+ }
+
+ public void setContact (Contact contact) {
+ this.contact = contact;
+ }
+
+ public Authorization getAuthorization () {
+ return authorization;
+ }
+
+ public void setAuthorization (Authorization authorization) {
+ this.authorization = authorization;
+ }
+
+ public static class Contact {
+ /**
+ * 联系人
+ **/
+ private String name = "";
+ /**
+ * 联系人url
+ **/
+ private String url = "";
+ /**
+ * 联系人email
+ **/
+ private String email = "";
+
+ public String getName () {
+ return name;
+ }
+
+ public void setName (String name) {
+ this.name = name;
+ }
+
+ public String getUrl () {
+ return url;
+ }
+
+ public void setUrl (String url) {
+ this.url = url;
+ }
+
+ public String getEmail () {
+ return email;
+ }
+
+ public void setEmail (String email) {
+ this.email = email;
+ }
+ }
+
+ public static class Authorization {
+ /**
+ * 鉴权策略ID,需要和SecurityReferences ID保持一致
+ */
+ private String name = "";
+
+ /**
+ * 需要开启鉴权URL的正则
+ */
+ private String authRegex = "^.*$";
+
+ /**
+ * 鉴权作用域列表
+ */
+ private List authorizationScopeList = new ArrayList<>();
+
+ private List tokenUrlList = new ArrayList<>();
+
+ public String getName () {
+ return name;
+ }
+
+ public void setName (String name) {
+ this.name = name;
+ }
+
+ public String getAuthRegex () {
+ return authRegex;
+ }
+
+ public void setAuthRegex (String authRegex) {
+ this.authRegex = authRegex;
+ }
+
+ public List getAuthorizationScopeList () {
+ return authorizationScopeList;
+ }
+
+ public void setAuthorizationScopeList (List authorizationScopeList) {
+ this.authorizationScopeList = authorizationScopeList;
+ }
+
+ public List getTokenUrlList () {
+ return tokenUrlList;
+ }
+
+ public void setTokenUrlList (List tokenUrlList) {
+ this.tokenUrlList = tokenUrlList;
+ }
+ }
+
+ public static class AuthorizationScope {
+ /**
+ * 作用域名称
+ */
+ private String scope = "";
+
+ /**
+ * 作用域描述
+ */
+ private String description = "";
+
+ public String getScope () {
+ return scope;
+ }
+
+ public void setScope (String scope) {
+ this.scope = scope;
+ }
+
+ public String getDescription () {
+ return description;
+ }
+
+ public void setDescription (String description) {
+ this.description = description;
+ }
+ }
+}
diff --git a/src/main/java/com/god/common/swagger/config/SwaggerWebConfiguration.java b/src/main/java/com/god/common/swagger/config/SwaggerWebConfiguration.java
new file mode 100644
index 0000000..05a1088
--- /dev/null
+++ b/src/main/java/com/god/common/swagger/config/SwaggerWebConfiguration.java
@@ -0,0 +1,18 @@
+package com.god.common.swagger.config;
+
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * swagger 资源映射路径
+ *
+ * @author god
+ */
+public class SwaggerWebConfiguration implements WebMvcConfigurer {
+ @Override
+ public void addResourceHandlers (ResourceHandlerRegistry registry) {
+ /** swagger-ui 地址 */
+ registry.addResourceHandler("/swagger-ui/**")
+ .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
+ }
+}
diff --git a/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000..749a52b
--- /dev/null
+++ b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,3 @@
+# com.god.common.swagger.config.SwaggerAutoConfiguration
+# com.god.common.swagger.config.SwaggerWebConfiguration
+# com.god.common.swagger.config.SwaggerBeanPostProcessor