commit 3544c1850ddfafd3e9698223b125c7e4491ae45c
Author: TangZhaoZhen <207525215@qq.com>
Date: Mon Oct 16 20:35:28 2023 +0800
初始化
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..a679ecd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+ com.four
+ four-common
+ 3.6.3
+
+ 4.0.0
+
+ four-common-swagger
+
+ 3.6.3
+
+
+ four-common-swagger系统接口
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${swagger.fox.version}
+
+
+
+
diff --git a/src/main/java/com/four/common/swagger/annotation/EnableCustomSwagger2.java b/src/main/java/com/four/common/swagger/annotation/EnableCustomSwagger2.java
new file mode 100644
index 0000000..8e31aa9
--- /dev/null
+++ b/src/main/java/com/four/common/swagger/annotation/EnableCustomSwagger2.java
@@ -0,0 +1,20 @@
+package com.four.common.swagger.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.springframework.context.annotation.Import;
+import com.four.common.swagger.config.SwaggerAutoConfiguration;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import({ SwaggerAutoConfiguration.class })
+public @interface EnableCustomSwagger2
+{
+
+}
diff --git a/src/main/java/com/four/common/swagger/config/SwaggerAutoConfiguration.java b/src/main/java/com/four/common/swagger/config/SwaggerAutoConfiguration.java
new file mode 100644
index 0000000..1b2d35c
--- /dev/null
+++ b/src/main/java/com/four/common/swagger/config/SwaggerAutoConfiguration.java
@@ -0,0 +1,123 @@
+package com.four.common.swagger.config;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+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.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+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;
+
+@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/four/common/swagger/config/SwaggerBeanPostProcessor.java b/src/main/java/com/four/common/swagger/config/SwaggerBeanPostProcessor.java
new file mode 100644
index 0000000..4155e77
--- /dev/null
+++ b/src/main/java/com/four/common/swagger/config/SwaggerBeanPostProcessor.java
@@ -0,0 +1,52 @@
+package com.four.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 ruoyi
+ */
+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/four/common/swagger/config/SwaggerProperties.java b/src/main/java/com/four/common/swagger/config/SwaggerProperties.java
new file mode 100644
index 0000000..ec1cd66
--- /dev/null
+++ b/src/main/java/com/four/common/swagger/config/SwaggerProperties.java
@@ -0,0 +1,343 @@
+package com.four.common.swagger.config;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/four/common/swagger/config/SwaggerWebConfiguration.java b/src/main/java/com/four/common/swagger/config/SwaggerWebConfiguration.java
new file mode 100644
index 0000000..6160995
--- /dev/null
+++ b/src/main/java/com/four/common/swagger/config/SwaggerWebConfiguration.java
@@ -0,0 +1,20 @@
+package com.four.common.swagger.config;
+
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * swagger 资源映射路径
+ *
+ * @author ruoyi
+ */
+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/");
+ }
+}
\ No newline at end of file
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..bec6612
--- /dev/null
+++ b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,3 @@
+# com.four.common.swagger.config.SwaggerAutoConfiguration
+# com.four.common.swagger.config.SwaggerWebConfiguration
+# com.four.common.swagger.config.SwaggerBeanPostProcessor