mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 08:57:17 +08:00
refactor(api-doc/web): 重构doc文档枚举展示处理,处理doc 文档全局响应格式
This commit is contained in:
@@ -48,15 +48,13 @@ 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.OpenApiHandler;
|
import top.continew.starter.apidoc.handler.OpenApiHandler;
|
||||||
import top.continew.starter.apidoc.util.EnumTypeUtils;
|
|
||||||
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
|
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
|
||||||
import top.continew.starter.core.enums.BaseEnum;
|
|
||||||
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API 文档自动配置
|
* API 文档自动配置
|
||||||
@@ -158,94 +156,14 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer {
|
|||||||
/**
|
/**
|
||||||
* 自定义参数配置(针对 BaseEnum 展示枚举值和描述)
|
* 自定义参数配置(针对 BaseEnum 展示枚举值和描述)
|
||||||
*
|
*
|
||||||
|
* @return {@link GenericEnumHandler }
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public ParameterCustomizer customParameterCustomizer() {
|
public GenericEnumHandler customParameterCustomizer() {
|
||||||
return (parameterModel, methodParameter) -> {
|
return new GenericEnumHandler();
|
||||||
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;
|
|
||||||
}
|
|
||||||
// 封装参数配置
|
|
||||||
this.configureSchema(parameterModel.getSchema(), parameterType);
|
|
||||||
// 自定义枚举描述
|
|
||||||
parameterModel.setDescription(description + "<span style='color:red'>" + this
|
|
||||||
.getDescMap(parameterType) + "</span>");
|
|
||||||
return parameterModel;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义参数配置(针对 BaseEnum 展示枚举值和描述)
|
|
||||||
*
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public PropertyCustomizer customPropertyCustomizer() {
|
|
||||||
return (schema, type) -> {
|
|
||||||
Class<?> rawClass;
|
|
||||||
// 获取原始类的类型
|
|
||||||
if (type.getType() instanceof SimpleType) {
|
|
||||||
rawClass = ((SimpleType)type.getType()).getRawClass();
|
|
||||||
} else if (type.getType() instanceof CollectionType) {
|
|
||||||
rawClass = ((CollectionType)type.getType()).getContentType().getRawClass();
|
|
||||||
} else {
|
|
||||||
rawClass = Object.class;
|
|
||||||
}
|
|
||||||
// 判断是否为 BaseEnum 的子类型
|
|
||||||
if (!ClassUtil.isAssignable(BaseEnum.class, rawClass)) {
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
// 封装参数配置
|
|
||||||
this.configureSchema(schema, rawClass);
|
|
||||||
// 自定义参数描述
|
|
||||||
schema.setDescription(schema.getDescription() + "<span style='color:red'>" + this
|
|
||||||
.getDescMap(rawClass) + "</span>");
|
|
||||||
return schema;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 封装 Schema 配置
|
|
||||||
*
|
|
||||||
* @param schema Schema
|
|
||||||
* @param enumClass 枚举类型
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
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 = EnumTypeUtils.getEnumValueTypeAsString(enumClass);
|
|
||||||
schema.setType(enumValueType);
|
|
||||||
switch (enumValueType) {
|
|
||||||
case "integer" -> schema.setFormat("int32");
|
|
||||||
case "long" -> schema.setFormat("int64");
|
|
||||||
case "number" -> schema.setFormat("double");
|
|
||||||
default -> schema.setFormat(enumValueType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取枚举描述 Map
|
|
||||||
*
|
|
||||||
* @param enumClass 枚举类型
|
|
||||||
* @return 枚举描述 Map
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
private Map<Object, String> getDescMap(Class<?> enumClass) {
|
|
||||||
BaseEnum[] enums = (BaseEnum[])enumClass.getEnumConstants();
|
|
||||||
return Arrays.stream(enums)
|
|
||||||
.collect(Collectors.toMap(BaseEnum::getValue, BaseEnum::getDescription, (a, b) -> a, LinkedHashMap::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void postConstruct() {
|
public void postConstruct() {
|
||||||
|
@@ -0,0 +1,102 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,132 @@
|
|||||||
|
package top.continew.starter.apidoc.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import top.continew.starter.core.enums.BaseEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口文档工具类
|
||||||
|
*
|
||||||
|
* @Author echo
|
||||||
|
* @date 2024/07/31
|
||||||
|
*/
|
||||||
|
public class DocUtils {
|
||||||
|
|
||||||
|
private DocUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取枚举值类型
|
||||||
|
*
|
||||||
|
* @param enumClass 枚举类型
|
||||||
|
* @return 枚举值类型
|
||||||
|
*/
|
||||||
|
public static String getEnumValueTypeAsString(Class<?> enumClass) {
|
||||||
|
// 获取枚举类实现的所有接口
|
||||||
|
Type[] interfaces = enumClass.getGenericInterfaces();
|
||||||
|
// 定义枚举值类型的映射
|
||||||
|
Map<Class<?>, 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<Object, String> getDescMap(Class<?> enumClass) {
|
||||||
|
BaseEnum[] enums = (BaseEnum[]) enumClass.getEnumConstants();
|
||||||
|
return Arrays.stream(enums)
|
||||||
|
.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());
|
||||||
|
}
|
||||||
|
}
|
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
import top.continew.starter.core.enums.BaseEnum;
|
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 枚举类型工具
|
|
||||||
*
|
|
||||||
* @author echo
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
public class EnumTypeUtils {
|
|
||||||
|
|
||||||
private EnumTypeUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取枚举值类型
|
|
||||||
*
|
|
||||||
* @param enumClass 枚举类型
|
|
||||||
* @return 枚举值类型
|
|
||||||
*/
|
|
||||||
public static String getEnumValueTypeAsString(Class<?> enumClass) {
|
|
||||||
try {
|
|
||||||
// 获取枚举类实现的所有接口
|
|
||||||
Type[] interfaces = enumClass.getGenericInterfaces();
|
|
||||||
// 遍历所有接口
|
|
||||||
for (Type type : interfaces) {
|
|
||||||
// 检查接口是否为参数化类型
|
|
||||||
if (type instanceof ParameterizedType parameterizedType) {
|
|
||||||
// 检查接口的原始类型是否为 BaseEnum
|
|
||||||
if (parameterizedType.getRawType() != BaseEnum.class) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Type actualType = parameterizedType.getActualTypeArguments()[0];
|
|
||||||
// 检查实际类型参数是否为类类型
|
|
||||||
if (actualType instanceof Class<?> actualClass) {
|
|
||||||
if (actualClass == Integer.class) {
|
|
||||||
return "integer";
|
|
||||||
} else if (actualClass == Long.class) {
|
|
||||||
return "long";
|
|
||||||
} else if (actualClass == Double.class) {
|
|
||||||
return "number";
|
|
||||||
} else if (actualClass == String.class) {
|
|
||||||
return "string";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
return "string";
|
|
||||||
}
|
|
||||||
}
|
|
@@ -37,6 +37,7 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局响应自动配置
|
* 全局响应自动配置
|
||||||
@@ -143,6 +144,16 @@ public class GlobalResponseAutoConfiguration {
|
|||||||
return messageSource;
|
return messageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpringDoc 通用响应处理 - 仅处理 doc 文档响应格式
|
||||||
|
*
|
||||||
|
* @return {@link DocGenericResponseHandler }
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public DocGenericResponseHandler genericResponseHandler() {
|
||||||
|
return new DocGenericResponseHandler();
|
||||||
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void postConstruct() {
|
public void postConstruct() {
|
||||||
log.debug("[ContiNew Starter] - Auto Configuration 'Web-Global Response' completed initialization.");
|
log.debug("[ContiNew Starter] - Auto Configuration 'Web-Global Response' completed initialization.");
|
||||||
|
@@ -0,0 +1,54 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -32,7 +32,7 @@ import java.util.Collections;
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "响应信息")
|
@Schema(description = "响应信息")
|
||||||
public class R implements Response {
|
public class R<T> implements Response {
|
||||||
|
|
||||||
private static final GlobalResponseProperties PROPERTIES = SpringUtil.getBean(GlobalResponseProperties.class);
|
private static final GlobalResponseProperties PROPERTIES = SpringUtil.getBean(GlobalResponseProperties.class);
|
||||||
private static final String DEFAULT_SUCCESS_CODE = PROPERTIES.getDefaultSuccessCode();
|
private static final String DEFAULT_SUCCESS_CODE = PROPERTIES.getDefaultSuccessCode();
|
||||||
@@ -68,7 +68,7 @@ public class R implements Response {
|
|||||||
* 响应数据
|
* 响应数据
|
||||||
*/
|
*/
|
||||||
@Schema(description = "响应数据")
|
@Schema(description = "响应数据")
|
||||||
private Object data = Collections.emptyMap();
|
private T data;
|
||||||
|
|
||||||
public R() {
|
public R() {
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ public class R implements Response {
|
|||||||
this.setMsg(msg);
|
this.setMsg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public R(String code, String msg, Object data) {
|
public R(String code, String msg, T data) {
|
||||||
this(code, msg);
|
this(code, msg);
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ public class R implements Response {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPayload(Object payload) {
|
public void setPayload(Object payload) {
|
||||||
this.data = payload;
|
this.data = (T)payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -123,11 +123,11 @@ public class R implements Response {
|
|||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getData() {
|
public T getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(Object data) {
|
public void setData(T data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user