diff --git a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/autoconfigure/SpringDocAutoConfiguration.java b/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/autoconfigure/SpringDocAutoConfiguration.java index 9a5e6408..6f423b74 100644 --- a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/autoconfigure/SpringDocAutoConfiguration.java +++ b/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/autoconfigure/SpringDocAutoConfiguration.java @@ -16,34 +16,24 @@ package top.continew.starter.apidoc.autoconfigure; -import cn.hutool.core.map.MapUtil; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; -import io.swagger.v3.oas.models.security.SecurityRequirement; -import io.swagger.v3.oas.models.security.SecurityScheme; import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springdoc.core.configuration.SpringDocConfiguration; -import org.springdoc.core.customizers.GlobalOpenApiCustomizer; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import top.continew.starter.apidoc.handler.BaseEnumParameterHandler; import top.continew.starter.core.autoconfigure.application.ApplicationProperties; import top.continew.starter.core.util.GeneralPropertySourceFactory; -import java.util.Map; - /** * API 文档自动配置 * @@ -52,7 +42,6 @@ import java.util.Map; */ @EnableWebMvc @AutoConfiguration(before = SpringDocConfiguration.class) -@EnableConfigurationProperties(SpringDocExtensionProperties.class) @PropertySource(value = "classpath:default-api-doc.yml", factory = GeneralPropertySourceFactory.class) public class SpringDocAutoConfiguration implements WebMvcConfigurer { @@ -68,7 +57,7 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer { */ @Bean @ConditionalOnMissingBean - public OpenAPI openApi(ApplicationProperties applicationProperties, SpringDocExtensionProperties properties) { + public OpenAPI openApi(ApplicationProperties applicationProperties) { Info info = new Info().title("%s %s".formatted(applicationProperties.getName(), "API 文档")) .version(applicationProperties.getVersion()) .description(applicationProperties.getDescription()); @@ -82,54 +71,9 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer { } OpenAPI openApi = new OpenAPI(); openApi.info(info); - Components components = properties.getComponents(); - if (components != null) { - openApi.components(components); - Map securitySchemeMap = components.getSecuritySchemes(); - if (MapUtil.isNotEmpty(securitySchemeMap)) { - SecurityRequirement securityRequirement = new SecurityRequirement(); - securitySchemeMap.keySet().forEach(securityRequirement::addList); - openApi.addSecurityItem(securityRequirement); - } - } return openApi; } - /** - * 全局自定义配置(全局添加鉴权参数) - */ - @Bean - @ConditionalOnMissingBean - public GlobalOpenApiCustomizer globalOpenApiCustomizer(SpringDocExtensionProperties properties) { - return openApi -> { - if (openApi.getPaths() != null) { - openApi.getPaths().forEach((path, pathItem) -> { - // 为所有接口添加鉴权 - Components components = properties.getComponents(); - if (components != null && MapUtil.isNotEmpty(components.getSecuritySchemes())) { - Map securitySchemeMap = components.getSecuritySchemes(); - pathItem.readOperations().forEach(operation -> { - SecurityRequirement securityRequirement = new SecurityRequirement(); - securitySchemeMap.keySet().forEach(securityRequirement::addList); - operation.addSecurityItem(securityRequirement); - }); - } - }); - } - }; - } - - /** - * 自定义 BaseEnum 枚举参数配置(针对实现了 BaseEnum 的枚举,优化其枚举值和描述展示) - * - * @return {@link BaseEnumParameterHandler } - * @since 2.4.0 - */ - @Bean - public BaseEnumParameterHandler customParameterCustomizer(ObjectMapper mapper) { - return new BaseEnumParameterHandler(mapper); - } - @PostConstruct public void postConstruct() { log.debug("[ContiNew Starter] - Auto Configuration 'ApiDoc' completed initialization."); diff --git a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/autoconfigure/SpringDocExtensionProperties.java b/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/autoconfigure/SpringDocExtensionProperties.java deleted file mode 100644 index fae1de38..00000000 --- a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/autoconfigure/SpringDocExtensionProperties.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *

- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.gnu.org/licenses/lgpl.html - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package top.continew.starter.apidoc.autoconfigure; - -import io.swagger.v3.oas.models.Components; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.NestedConfigurationProperty; - -/** - * API 文档扩展配置属性 - * - * @author Charles7c - * @since 1.0.1 - */ -@ConfigurationProperties("springdoc") -public class SpringDocExtensionProperties { - - /** - * 组件配置(包括鉴权配置等) - */ - @NestedConfigurationProperty - private Components components; - - public Components getComponents() { - return components; - } - - public void setComponents(Components components) { - this.components = components; - } -} diff --git a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/handler/BaseEnumParameterHandler.java b/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/handler/BaseEnumParameterHandler.java deleted file mode 100644 index 5125e952..00000000 --- a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/handler/BaseEnumParameterHandler.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *

- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.gnu.org/licenses/lgpl.html - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package top.continew.starter.apidoc.handler; - -import cn.hutool.core.text.CharSequenceUtil; -import cn.hutool.core.util.ClassUtil; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.CollectionType; -import com.fasterxml.jackson.databind.type.SimpleType; -import io.swagger.v3.core.converter.AnnotatedType; -import io.swagger.v3.core.converter.ModelConverter; -import io.swagger.v3.core.converter.ModelConverterContext; -import io.swagger.v3.core.jackson.ModelResolver; -import io.swagger.v3.oas.models.media.Schema; -import io.swagger.v3.oas.models.parameters.Parameter; -import org.springdoc.core.customizers.ParameterCustomizer; -import org.springframework.core.MethodParameter; -import top.continew.starter.apidoc.util.ApiDocUtils; -import top.continew.starter.core.enums.BaseEnum; - -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -/** - * 自定义 BaseEnum 枚举参数处理器 - *

- * 针对实现了 BaseEnum 的枚举,优化其枚举值和描述展示 - *

- * - * @author echo - * @since 2.5.2 - */ -public class BaseEnumParameterHandler extends ModelResolver implements ParameterCustomizer { - - public BaseEnumParameterHandler(ObjectMapper mapper) { - super(mapper); - } - - @Override - public Parameter customize(Parameter parameterModel, MethodParameter methodParameter) { - Class parameterType = methodParameter.getParameterType(); - // 判断是否为 BaseEnum 的子类型 - if (!ClassUtil.isAssignable(BaseEnum.class, parameterType)) { - return parameterModel; - } - String description = parameterModel.getDescription(); - if (CharSequenceUtil.contains(description, "color:red")) { - return parameterModel; - } - // 自定义枚举描述并封装参数配置 - configureSchema(parameterModel.getSchema(), parameterType); - parameterModel.setDescription(appendEnumDescription(description, parameterType)); - return parameterModel; - } - - @Override - public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator chain) { - Schema resolve = super.resolve(type, context, chain); - Class rawClass = resolveRawClass(type.getType()); - // 判断是否为 BaseEnum 的子类型 - if (!ClassUtil.isAssignable(BaseEnum.class, rawClass)) { - return resolve; - } - - // 自定义参数描述并封装参数配置 - configureSchema(resolve, rawClass); - resolve.setDescription(appendEnumDescription(resolve.getDescription(), rawClass)); - return resolve; - } - - /** - * 封装 Schema 配置 - * - * @param schema Schema - * @param enumClass 枚举类型 - */ - private void configureSchema(Schema schema, Class enumClass) { - BaseEnum[] enums = (BaseEnum[])enumClass.getEnumConstants(); - List valueList = Arrays.stream(enums).map(e -> e.getValue().toString()).toList(); - schema.setEnum(valueList); - String enumValueType = ApiDocUtils.getEnumValueTypeAsString(enumClass); - schema.setType(enumValueType); - schema.setFormat(ApiDocUtils.resolveFormat(enumValueType)); - } - - /** - * 追加枚举描述 - * - * @param originalDescription 原始描述 - * @param enumClass 枚举类型 - * @return 追加后的描述字符串 - */ - private String appendEnumDescription(String originalDescription, Class enumClass) { - return originalDescription + "" + ApiDocUtils.getDescMap(enumClass) + ""; - } - - /** - * 解析原始类 - * - * @param type 类型 - * @return 原始类的 Class 对象 - */ - private Class resolveRawClass(Type type) { - if (type instanceof SimpleType simpleType) { - return simpleType.getRawClass(); - } else if (type instanceof CollectionType collectionType) { - return collectionType.getContentType().getRawClass(); - } else { - return Object.class; - } - } -} diff --git a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/util/ApiDocUtils.java b/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/util/ApiDocUtils.java index d7340577..8f8c2ef5 100644 --- a/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/util/ApiDocUtils.java +++ b/continew-starter-api-doc/src/main/java/top/continew/starter/apidoc/util/ApiDocUtils.java @@ -17,15 +17,6 @@ package top.continew.starter.apidoc.util; import org.springdoc.core.models.GroupedOpenApi; -import org.springframework.web.bind.annotation.RestController; -import top.continew.starter.core.enums.BaseEnum; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.stream.Collectors; /** * 接口文档工具类 @@ -63,84 +54,4 @@ public class ApiDocUtils { public static GroupedOpenApi buildGroupedOpenApi(String group, String displayName, String... pathsToMatch) { return GroupedOpenApi.builder().group(group).displayName(displayName).pathsToMatch(pathsToMatch).build(); } - - /** - * 获取枚举值类型 - * - * @param enumClass 枚举类型 - * @return 枚举值类型 - */ - public static String getEnumValueTypeAsString(Class enumClass) { - // 获取枚举类实现的所有接口 - Type[] interfaces = enumClass.getGenericInterfaces(); - // 定义枚举值类型的映射 - Map, String> typeMap = Map - .of(Integer.class, "integer", Long.class, "long", Double.class, "number", String.class, "string"); - // 遍历所有接口 - for (Type type : interfaces) { - // 检查接口是否为参数化类型并且原始类型为 BaseEnum - if (type instanceof ParameterizedType parameterizedType && parameterizedType - .getRawType() == BaseEnum.class) { - Type actualType = parameterizedType.getActualTypeArguments()[0]; - // 检查实际类型参数是否为类类型,并返回对应的字符串类型 - if (actualType instanceof Class actualClass) { - return typeMap.getOrDefault(actualClass, "string"); - } - } - } - // 默认返回 "string" 类型 - return "string"; - } - - /** - * 解析枚举值的格式 - * - * @param enumValueType 枚举值类型 - * @return String 格式化类型 - */ - public static String resolveFormat(String enumValueType) { - return switch (enumValueType) { - case "integer" -> "int32"; - case "long" -> "int64"; - case "number" -> "double"; - default -> enumValueType; - }; - } - - /** - * 具有 RestController 注释,既检查是否继承了BaseController - * - * @param clazz clazz - * @return boolean - */ - public static boolean hasRestControllerAnnotation(Class clazz) { - // 如果注释包含 RestController 注解,则返回 true - if (clazz.isAnnotationPresent(RestController.class)) { - return true; - } - // 递归检查父类 - Class superClass = clazz.getSuperclass(); - // 循环检查父类 - while (superClass != null && !superClass.equals(Object.class)) { - // 如果父类包含 RestController 注解,则返回 true - if (hasRestControllerAnnotation(superClass)) { - return true; - } - // 递归检查接口 - superClass = superClass.getSuperclass(); - } - return false; - } - - /** - * 获取枚举描述 Map - * - * @param enumClass 枚举类型 - * @return 枚举描述 Map - */ - public static Map getDescMap(Class enumClass) { - BaseEnum[] enums = (BaseEnum[])enumClass.getEnumConstants(); - return Arrays.stream(enums) - .collect(Collectors.toMap(BaseEnum::getValue, BaseEnum::getDescription, (a, b) -> a, LinkedHashMap::new)); - } } \ No newline at end of file diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/util/GeneralPropertySourceFactory.java b/continew-starter-core/src/main/java/top/continew/starter/core/util/GeneralPropertySourceFactory.java index 1c27a638..3ca91a38 100644 --- a/continew-starter-core/src/main/java/top/continew/starter/core/util/GeneralPropertySourceFactory.java +++ b/continew-starter-core/src/main/java/top/continew/starter/core/util/GeneralPropertySourceFactory.java @@ -30,7 +30,8 @@ import java.io.IOException; * 通用配置文件读取工厂 *

* DefaultPropertySourceFactory 仅支持 properties - * 配置文件读取,详见:YAMLShortcomings + * 配置文件读取,详见:YAMLShortcomings *

* * @author Charles7c diff --git a/continew-starter-dependencies/pom.xml b/continew-starter-dependencies/pom.xml index 5ff171a2..89a0cc8f 100644 --- a/continew-starter-dependencies/pom.xml +++ b/continew-starter-dependencies/pom.xml @@ -62,7 +62,7 @@ 2.9.0 - 1.1.0 + 1.1.5 2.2.36