mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 20:57:23 +08:00
chore(api-doc): 优化部分代码
This commit is contained in:
@@ -17,16 +17,11 @@
|
|||||||
package top.continew.starter.apidoc.autoconfigure;
|
package top.continew.starter.apidoc.autoconfigure;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ClassUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
|
||||||
import com.fasterxml.jackson.databind.type.SimpleType;
|
|
||||||
import io.swagger.v3.oas.models.Components;
|
import io.swagger.v3.oas.models.Components;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.info.Contact;
|
import io.swagger.v3.oas.models.info.Contact;
|
||||||
import io.swagger.v3.oas.models.info.Info;
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
import io.swagger.v3.oas.models.info.License;
|
import io.swagger.v3.oas.models.info.License;
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
|
||||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
@@ -48,7 +43,7 @@ import org.springframework.http.CacheControl;
|
|||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
import top.continew.starter.apidoc.handler.GenericEnumHandler;
|
import top.continew.starter.apidoc.handler.BaseEnumParameterHandler;
|
||||||
import top.continew.starter.apidoc.handler.OpenApiHandler;
|
import top.continew.starter.apidoc.handler.OpenApiHandler;
|
||||||
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
|
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
|
||||||
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
||||||
@@ -154,17 +149,16 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义参数配置(针对 BaseEnum 展示枚举值和描述)
|
* 自定义 BaseEnum 枚举参数配置(针对实现了 BaseEnum 的枚举,优化其枚举值和描述展示)
|
||||||
*
|
*
|
||||||
* @return {@link GenericEnumHandler }
|
* @return {@link BaseEnumParameterHandler }
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public GenericEnumHandler customParameterCustomizer() {
|
public BaseEnumParameterHandler customParameterCustomizer() {
|
||||||
return new GenericEnumHandler();
|
return new BaseEnumParameterHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void postConstruct() {
|
public void postConstruct() {
|
||||||
log.debug("[ContiNew Starter] - Auto Configuration 'ApiDoc' completed initialization.");
|
log.debug("[ContiNew Starter] - Auto Configuration 'ApiDoc' completed initialization.");
|
||||||
|
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* 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.util.ClassUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
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.oas.models.media.Schema;
|
||||||
|
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||||
|
import org.springdoc.core.customizers.ParameterCustomizer;
|
||||||
|
import org.springdoc.core.customizers.PropertyCustomizer;
|
||||||
|
import org.springframework.core.MethodParameter;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import top.continew.starter.apidoc.util.DocUtils;
|
||||||
|
import top.continew.starter.core.enums.BaseEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义 BaseEnum 枚举参数处理器
|
||||||
|
* <p>
|
||||||
|
* 针对实现了 BaseEnum 的枚举,优化其枚举值和描述展示
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author echo
|
||||||
|
* @since 2.5.2
|
||||||
|
*/
|
||||||
|
public class BaseEnumParameterHandler implements ParameterCustomizer, PropertyCustomizer {
|
||||||
|
|
||||||
|
@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 (StrUtil.contains(description, "color:red")) {
|
||||||
|
return parameterModel;
|
||||||
|
}
|
||||||
|
// 自定义枚举描述并封装参数配置
|
||||||
|
configureSchema(parameterModel.getSchema(), parameterType);
|
||||||
|
parameterModel.setDescription(appendEnumDescription(description, parameterType));
|
||||||
|
return parameterModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Schema customize(Schema schema, AnnotatedType type) {
|
||||||
|
Class<?> rawClass = resolveRawClass(type.getType());
|
||||||
|
// 判断是否为 BaseEnum 的子类型
|
||||||
|
if (!ClassUtil.isAssignable(BaseEnum.class, rawClass)) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
// 自定义参数描述并封装参数配置
|
||||||
|
configureSchema(schema, rawClass);
|
||||||
|
schema.setDescription(appendEnumDescription(schema.getDescription(), rawClass));
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装 Schema 配置
|
||||||
|
*
|
||||||
|
* @param schema Schema
|
||||||
|
* @param enumClass 枚举类型
|
||||||
|
*/
|
||||||
|
private void configureSchema(Schema schema, Class<?> enumClass) {
|
||||||
|
BaseEnum[] enums = (BaseEnum[])enumClass.getEnumConstants();
|
||||||
|
List<String> valueList = Arrays.stream(enums).map(e -> e.getValue().toString()).toList();
|
||||||
|
schema.setEnum(valueList);
|
||||||
|
String enumValueType = DocUtils.getEnumValueTypeAsString(enumClass);
|
||||||
|
schema.setType(enumValueType);
|
||||||
|
schema.setFormat(DocUtils.resolveFormat(enumValueType));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加枚举描述
|
||||||
|
*
|
||||||
|
* @param originalDescription 原始描述
|
||||||
|
* @param enumClass 枚举类型
|
||||||
|
* @return 追加后的描述字符串
|
||||||
|
*/
|
||||||
|
private String appendEnumDescription(String originalDescription, Class<?> enumClass) {
|
||||||
|
return originalDescription + "<span style='color:red'>" + DocUtils.getDescMap(enumClass) + "</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析原始类
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,102 +0,0 @@
|
|||||||
package top.continew.starter.apidoc.handler;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ClassUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
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.oas.models.media.Schema;
|
|
||||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
|
||||||
import org.springdoc.core.customizers.ParameterCustomizer;
|
|
||||||
import org.springdoc.core.customizers.PropertyCustomizer;
|
|
||||||
import org.springframework.core.MethodParameter;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import top.continew.starter.apidoc.util.DocUtils;
|
|
||||||
import top.continew.starter.core.enums.BaseEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 枚举处理程序
|
|
||||||
* 主要实现对 继承了 BaseEnum 类型的枚举参数和属性进行处理
|
|
||||||
*
|
|
||||||
* @Author echo
|
|
||||||
* @date 2024/08/12
|
|
||||||
*/
|
|
||||||
public class GenericEnumHandler implements ParameterCustomizer, PropertyCustomizer {
|
|
||||||
@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 (StrUtil.contains(description, "color:red")) {
|
|
||||||
return parameterModel;
|
|
||||||
}
|
|
||||||
// 自定义枚举描述并封装参数配置
|
|
||||||
configureSchema(parameterModel.getSchema(), parameterType);
|
|
||||||
parameterModel.setDescription(appendEnumDescription(description, parameterType));
|
|
||||||
return parameterModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Schema customize(Schema schema, AnnotatedType type) {
|
|
||||||
Class<?> rawClass = resolveRawClass(type.getType());
|
|
||||||
// 判断是否为 BaseEnum 的子类型
|
|
||||||
if (!ClassUtil.isAssignable(BaseEnum.class, rawClass)) {
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
// 自定义参数描述并封装参数配置
|
|
||||||
configureSchema(schema, rawClass);
|
|
||||||
schema.setDescription(appendEnumDescription(schema.getDescription(), rawClass));
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 封装 Schema 配置
|
|
||||||
*
|
|
||||||
* @param schema Schema
|
|
||||||
* @param enumClass 枚举类型
|
|
||||||
*/
|
|
||||||
private void configureSchema(Schema schema, Class<?> enumClass) {
|
|
||||||
BaseEnum[] enums = (BaseEnum[]) enumClass.getEnumConstants();
|
|
||||||
List<String> valueList = Arrays.stream(enums)
|
|
||||||
.map(e -> e.getValue().toString()).toList();
|
|
||||||
schema.setEnum(valueList);
|
|
||||||
String enumValueType = DocUtils.getEnumValueTypeAsString(enumClass);
|
|
||||||
schema.setType(enumValueType);
|
|
||||||
schema.setFormat(DocUtils.resolveFormat(enumValueType));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 追加枚举描述
|
|
||||||
*
|
|
||||||
* @param originalDescription 原始描述
|
|
||||||
* @param enumClass 枚举类型
|
|
||||||
* @return 追加后的描述字符串
|
|
||||||
*/
|
|
||||||
private String appendEnumDescription(String originalDescription, Class<?> enumClass) {
|
|
||||||
return originalDescription + "<span style='color:red'>" + DocUtils.getDescMap(enumClass) + "</span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析原始类
|
|
||||||
*
|
|
||||||
* @param type 类型
|
|
||||||
* @return 原始类的 Class 对象
|
|
||||||
*/
|
|
||||||
private Class<?> resolveRawClass(Type type) {
|
|
||||||
if (type instanceof SimpleType) {
|
|
||||||
return ((SimpleType) type).getRawClass();
|
|
||||||
} else if (type instanceof CollectionType) {
|
|
||||||
return ((CollectionType) type).getContentType().getRawClass();
|
|
||||||
} else {
|
|
||||||
return Object.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,15 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* 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.util;
|
package top.continew.starter.apidoc.util;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import top.continew.starter.core.enums.BaseEnum;
|
import top.continew.starter.core.enums.BaseEnum;
|
||||||
@@ -17,8 +28,8 @@ import top.continew.starter.core.enums.BaseEnum;
|
|||||||
/**
|
/**
|
||||||
* 接口文档工具类
|
* 接口文档工具类
|
||||||
*
|
*
|
||||||
* @Author echo
|
* @author echo
|
||||||
* @date 2024/07/31
|
* @since 2.5.2
|
||||||
*/
|
*/
|
||||||
public class DocUtils {
|
public class DocUtils {
|
||||||
|
|
||||||
@@ -35,16 +46,13 @@ public class DocUtils {
|
|||||||
// 获取枚举类实现的所有接口
|
// 获取枚举类实现的所有接口
|
||||||
Type[] interfaces = enumClass.getGenericInterfaces();
|
Type[] interfaces = enumClass.getGenericInterfaces();
|
||||||
// 定义枚举值类型的映射
|
// 定义枚举值类型的映射
|
||||||
Map<Class<?>, String> typeMap = Map.of(
|
Map<Class<?>, String> typeMap = Map
|
||||||
Integer.class, "integer",
|
.of(Integer.class, "integer", Long.class, "long", Double.class, "number", String.class, "string");
|
||||||
Long.class, "long",
|
|
||||||
Double.class, "number",
|
|
||||||
String.class, "string"
|
|
||||||
);
|
|
||||||
// 遍历所有接口
|
// 遍历所有接口
|
||||||
for (Type type : interfaces) {
|
for (Type type : interfaces) {
|
||||||
// 检查接口是否为参数化类型并且原始类型为 BaseEnum
|
// 检查接口是否为参数化类型并且原始类型为 BaseEnum
|
||||||
if (type instanceof ParameterizedType parameterizedType && parameterizedType.getRawType() == BaseEnum.class) {
|
if (type instanceof ParameterizedType parameterizedType && parameterizedType
|
||||||
|
.getRawType() == BaseEnum.class) {
|
||||||
Type actualType = parameterizedType.getActualTypeArguments()[0];
|
Type actualType = parameterizedType.getActualTypeArguments()[0];
|
||||||
// 检查实际类型参数是否为类类型,并返回对应的字符串类型
|
// 检查实际类型参数是否为类类型,并返回对应的字符串类型
|
||||||
if (actualType instanceof Class<?> actualClass) {
|
if (actualType instanceof Class<?> actualClass) {
|
||||||
@@ -71,9 +79,8 @@ public class DocUtils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 具有RestController 注释 既检查是否继承了BaseController
|
* 具有 RestController 注释,既检查是否继承了BaseController
|
||||||
*
|
*
|
||||||
* @param clazz clazz
|
* @param clazz clazz
|
||||||
* @return boolean
|
* @return boolean
|
||||||
@@ -104,29 +111,8 @@ public class DocUtils {
|
|||||||
* @return 枚举描述 Map
|
* @return 枚举描述 Map
|
||||||
*/
|
*/
|
||||||
public static Map<Object, String> getDescMap(Class<?> enumClass) {
|
public static Map<Object, String> getDescMap(Class<?> enumClass) {
|
||||||
BaseEnum[] enums = (BaseEnum[]) enumClass.getEnumConstants();
|
BaseEnum[] enums = (BaseEnum[])enumClass.getEnumConstants();
|
||||||
return Arrays.stream(enums)
|
return Arrays.stream(enums)
|
||||||
.collect(Collectors.toMap(BaseEnum::getValue, BaseEnum::getDescription, (a, b) -> a, LinkedHashMap::new));
|
.collect(Collectors.toMap(BaseEnum::getValue, BaseEnum::getDescription, (a, b) -> a, LinkedHashMap::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 将collection转化为Set集合,但是两者的泛型不同<br>
|
|
||||||
* <B>{@code Collection<E> ------> Set<T> } </B>
|
|
||||||
*
|
|
||||||
* @param collection 需要转化的集合
|
|
||||||
* @param function collection中的泛型转化为set泛型的lambda表达式
|
|
||||||
* @param <E> collection中的泛型
|
|
||||||
* @param <T> Set中的泛型
|
|
||||||
* @return 转化后的Set
|
|
||||||
*/
|
|
||||||
public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
|
|
||||||
if (CollUtil.isEmpty(collection) || function == null) {
|
|
||||||
return CollUtil.newHashSet();
|
|
||||||
}
|
|
||||||
return collection
|
|
||||||
.stream()
|
|
||||||
.map(function)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* 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.web.autoconfigure.response;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.reflect.TypeUtils;
|
||||||
|
import org.springdoc.core.parsers.ReturnTypeParser;
|
||||||
|
import org.springframework.core.MethodParameter;
|
||||||
|
import top.continew.starter.apidoc.util.DocUtils;
|
||||||
|
import top.continew.starter.web.model.R;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpringDoc 全局响应处理器
|
||||||
|
* <p>
|
||||||
|
* 接口文档全局添加响应格式 {@link R}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author echo
|
||||||
|
* @since 2.5.2
|
||||||
|
*/
|
||||||
|
public class ApiDocGlobalResponseHandler implements ReturnTypeParser {
|
||||||
|
|
||||||
|
private static final Class<R> R_TYPE = R.class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取返回类型
|
||||||
|
*
|
||||||
|
* @param methodParameter 方法参数
|
||||||
|
* @return {@link Type }
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Type getReturnType(MethodParameter methodParameter) {
|
||||||
|
// 获取返回类型
|
||||||
|
Type returnType = ReturnTypeParser.super.getReturnType(methodParameter);
|
||||||
|
// 判断是否具有 RestController 注解
|
||||||
|
if (!DocUtils.hasRestControllerAnnotation(methodParameter.getContainingClass())) {
|
||||||
|
return returnType;
|
||||||
|
}
|
||||||
|
// 如果为 R<T> 则直接返回
|
||||||
|
if (returnType.getTypeName().contains("top.continew.starter.web.model.R")) {
|
||||||
|
return returnType;
|
||||||
|
}
|
||||||
|
// 如果是 void类型,则返回 R<Void>
|
||||||
|
if (returnType == void.class || returnType == Void.class) {
|
||||||
|
return TypeUtils.parameterize(R_TYPE, Void.class);
|
||||||
|
}
|
||||||
|
// 返回 R<T>
|
||||||
|
return TypeUtils.parameterize(R_TYPE, returnType);
|
||||||
|
}
|
||||||
|
}
|
@@ -37,7 +37,6 @@ import top.continew.starter.core.constant.PropertiesConstants;
|
|||||||
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import top.continew.starter.web.handler.DocGenericResponseHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局响应自动配置
|
* 全局响应自动配置
|
||||||
@@ -145,13 +144,14 @@ public class GlobalResponseAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SpringDoc 通用响应处理 - 仅处理 doc 文档响应格式
|
* SpringDoc 全局响应处理器
|
||||||
*
|
*
|
||||||
* @return {@link DocGenericResponseHandler }
|
* @return {@link ApiDocGlobalResponseHandler }
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public DocGenericResponseHandler genericResponseHandler() {
|
@ConditionalOnMissingBean
|
||||||
return new DocGenericResponseHandler();
|
public ApiDocGlobalResponseHandler apiDocGlobalResponseHandler() {
|
||||||
|
return new ApiDocGlobalResponseHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
|
@@ -1,54 +0,0 @@
|
|||||||
package top.continew.starter.web.handler;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.reflect.TypeUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springdoc.core.parsers.ReturnTypeParser;
|
|
||||||
import org.springframework.core.MethodParameter;
|
|
||||||
import top.continew.starter.apidoc.util.DocUtils;
|
|
||||||
import top.continew.starter.web.model.R;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SpringDoc 通用响应处理程序 --仅处理 doc 文档响应格式
|
|
||||||
* <p>
|
|
||||||
全局添加响应格式 {@link R}
|
|
||||||
*
|
|
||||||
* @Author echo
|
|
||||||
* @date 2024/08/12
|
|
||||||
*/
|
|
||||||
public class DocGenericResponseHandler implements ReturnTypeParser {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(DocGenericResponseHandler.class);
|
|
||||||
|
|
||||||
private static final Class<R> R_TYPE = R.class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取返回类型
|
|
||||||
*
|
|
||||||
* @param methodParameter 方法参数
|
|
||||||
* @return {@link Type }
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Type getReturnType(MethodParameter methodParameter) {
|
|
||||||
// 获取返回类型
|
|
||||||
Type returnType = ReturnTypeParser.super.getReturnType(methodParameter);
|
|
||||||
|
|
||||||
// 判断是否具有RestController 注解
|
|
||||||
if (!DocUtils.hasRestControllerAnnotation(methodParameter.getContainingClass())) {
|
|
||||||
return returnType;
|
|
||||||
}
|
|
||||||
// 如果为R<T> 则直接返回
|
|
||||||
if (returnType.getTypeName().contains("top.continew.starter.web.model.R")) {
|
|
||||||
return returnType;
|
|
||||||
}
|
|
||||||
// 如果是void类型,则返回R<Void>
|
|
||||||
if (returnType == void.class || returnType == Void.class) {
|
|
||||||
return TypeUtils.parameterize(R_TYPE, Void.class);
|
|
||||||
}
|
|
||||||
// 返回R<T>
|
|
||||||
return TypeUtils.parameterize(R_TYPE, returnType);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -23,8 +23,6 @@ import com.feiniaojin.gracefulresponse.data.ResponseStatus;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import top.continew.starter.web.autoconfigure.response.GlobalResponseProperties;
|
import top.continew.starter.web.autoconfigure.response.GlobalResponseProperties;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应信息
|
* 响应信息
|
||||||
*
|
*
|
||||||
@@ -49,7 +47,7 @@ public class R<T> implements Response {
|
|||||||
/**
|
/**
|
||||||
* 状态信息
|
* 状态信息
|
||||||
*/
|
*/
|
||||||
@Schema(description = "状态信息", example = "操作成功")
|
@Schema(description = "状态信息", example = "ok")
|
||||||
private String msg;
|
private String msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user