mirror of https://gitee.com/stylefeng/roses
新增扫描list集合的方法(待完善)
parent
af10986b45
commit
d40af1f6d7
|
@ -59,6 +59,12 @@ public class FieldMetadata {
|
|||
@ChineseDescription("字段类型")
|
||||
private String fieldClassType;
|
||||
|
||||
/**
|
||||
* 字段类型路径,例如:java.long.String
|
||||
*/
|
||||
@ChineseDescription("字段类型路径")
|
||||
private String fieldClassPath;
|
||||
|
||||
/**
|
||||
* 字段名称,例如:createUser
|
||||
*/
|
||||
|
|
|
@ -26,15 +26,14 @@ package cn.stylefeng.roses.kernel.scanner.api.util;
|
|||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.TypeUtil;
|
||||
import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest;
|
||||
import cn.stylefeng.roses.kernel.scanner.api.annotation.field.ChineseDescription;
|
||||
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -45,6 +44,8 @@ import java.util.*;
|
|||
*/
|
||||
public class ClassReflectUtil {
|
||||
|
||||
private static Map<String, String> runingMap = new HashMap<>(2);
|
||||
|
||||
/**
|
||||
* 获取一个类的所有字段描述
|
||||
*
|
||||
|
@ -54,83 +55,123 @@ public class ClassReflectUtil {
|
|||
* @date 2020/12/8 18:27
|
||||
*/
|
||||
public static Set<FieldMetadata> getClassFieldDescription(Class<?> clazz) {
|
||||
|
||||
HashSet<FieldMetadata> fieldDescriptions = new HashSet<>();
|
||||
|
||||
if (clazz == null) {
|
||||
return fieldDescriptions;
|
||||
}
|
||||
|
||||
// 查询本类是否正在进行解析(防止死循环)
|
||||
String runing = runingMap.get(clazz.getName());
|
||||
|
||||
// 返回null则标识这个类正在运行,则不对该类再进行解析
|
||||
if (ObjectUtil.isNotEmpty(runing)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取该类和该类所有父类的属性
|
||||
while (clazz != null){
|
||||
while (clazz != null) {
|
||||
runingMap.put(clazz.getName(), clazz.getName());
|
||||
// 获取类中的所有字段
|
||||
Field[] declaredFields = ClassUtil.getDeclaredFields(clazz);
|
||||
|
||||
for (Field declaredField : declaredFields) {
|
||||
|
||||
FieldMetadata fieldDescription = new FieldMetadata();
|
||||
|
||||
// 生成uuid,给前端用
|
||||
fieldDescription.setMetadataId(IdUtil.fastSimpleUUID());
|
||||
|
||||
// 获取字段的名称
|
||||
String name = declaredField.getName();
|
||||
fieldDescription.setFieldName(name);
|
||||
|
||||
// 获取字段的类型
|
||||
Class<?> declaredFieldType = declaredField.getType();
|
||||
fieldDescription.setFieldClassType(declaredFieldType.getSimpleName());
|
||||
|
||||
// 如果字段类型是Object类型,则遍历Object类型里的字段
|
||||
if (BaseRequest.class.isAssignableFrom(declaredFieldType)) {
|
||||
fieldDescription.setGenericFieldMetadata(getClassFieldDescription(declaredFieldType));
|
||||
}
|
||||
|
||||
// 如果是泛型类型,遍历泛泛型的class类型里的字段
|
||||
if (Collection.class.isAssignableFrom(declaredFieldType)) {
|
||||
Class<?> genericClass = TypeUtil.getClass(TypeUtil.getTypeArgument(TypeUtil.getType(declaredField)));
|
||||
if (BaseRequest.class.isAssignableFrom(genericClass)) {
|
||||
fieldDescription.setGenericFieldMetadata(getClassFieldDescription(genericClass));
|
||||
}
|
||||
}
|
||||
|
||||
// 获取字段的所有注解
|
||||
Annotation[] annotations = declaredField.getAnnotations();
|
||||
if (annotations != null && annotations.length > 0) {
|
||||
|
||||
// 设置字段的所有注解
|
||||
fieldDescription.setAnnotations(annotationsToStrings(annotations));
|
||||
|
||||
// 遍历字段上的所有注解,找到带groups属性的,按group分类组装注解
|
||||
Map<String, Set<String>> groupAnnotations = new HashMap<>();
|
||||
for (Annotation annotation : annotations) {
|
||||
Class<?>[] validateGroupsClasses = invokeAnnotationMethodIgnoreError(annotation, "groups", Class[].class);
|
||||
if (validateGroupsClasses != null) {
|
||||
for (Class<?> validateGroupsClass : validateGroupsClasses) {
|
||||
addGroupValidateAnnotation(annotation, validateGroupsClass, groupAnnotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置分组注解
|
||||
fieldDescription.setGroupValidationMessage(groupAnnotations);
|
||||
|
||||
// 填充字段的中文名称
|
||||
ChineseDescription chineseDescription = declaredField.getAnnotation(ChineseDescription.class);
|
||||
if (chineseDescription != null) {
|
||||
fieldDescription.setChineseName(chineseDescription.value());
|
||||
}
|
||||
}
|
||||
|
||||
// 获取字段元数据
|
||||
FieldMetadata fieldDescription = getFieldMetadata(declaredField);
|
||||
fieldDescriptions.add(fieldDescription);
|
||||
}
|
||||
|
||||
runingMap.remove(clazz.getName());
|
||||
// 获取本类的父类
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
|
||||
return fieldDescriptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段详情
|
||||
*
|
||||
* @param declaredField 字段
|
||||
* @return {@link cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata}
|
||||
* @author majianguo
|
||||
* @date 2021/6/23 上午10:03
|
||||
**/
|
||||
private static FieldMetadata getFieldMetadata(Field declaredField) {
|
||||
FieldMetadata fieldDescription = new FieldMetadata();
|
||||
|
||||
// 生成uuid,给前端用
|
||||
fieldDescription.setMetadataId(IdUtil.fastSimpleUUID());
|
||||
|
||||
// 获取字段的名称
|
||||
String name = declaredField.getName();
|
||||
fieldDescription.setFieldName(name);
|
||||
|
||||
// 获取字段的类型
|
||||
Class<?> declaredFieldType = declaredField.getType();
|
||||
fieldDescription.setFieldClassType(declaredFieldType.getSimpleName());
|
||||
fieldDescription.setFieldClassPath(declaredFieldType.getName());
|
||||
|
||||
// 如果字段类型是Object类型,则遍历Object类型里的字段
|
||||
if (BaseRequest.class.isAssignableFrom(declaredFieldType)) {
|
||||
fieldDescription.setGenericFieldMetadata(getClassFieldDescription(declaredFieldType));
|
||||
} else if (List.class.isAssignableFrom(declaredFieldType)) {
|
||||
// 如果是集合类型,则处理集合里面的字段
|
||||
Type genericType = declaredField.getGenericType();
|
||||
ParameterizedType pt = (ParameterizedType)genericType;
|
||||
// 得到泛型里的class类型对象
|
||||
Class<?> actualTypeArgument = (Class<?>)pt.getActualTypeArguments()[0];
|
||||
// 基本类型处理
|
||||
if (actualTypeArgument.isPrimitive() || "java.lang".equals(actualTypeArgument.getPackage().getName()) || "java.util".equals(actualTypeArgument.getPackage().getName())) {
|
||||
FieldMetadata item = new FieldMetadata();
|
||||
item.setMetadataId(IdUtil.fastSimpleUUID());
|
||||
item.setFieldName(actualTypeArgument.getName());
|
||||
item.setFieldClassType(actualTypeArgument.getTypeName());
|
||||
// 填充字段的中文名称
|
||||
ChineseDescription chineseDescription = declaredField.getAnnotation(ChineseDescription.class);
|
||||
if (chineseDescription != null) {
|
||||
item.setChineseName(chineseDescription.value());
|
||||
}
|
||||
fieldDescription.setGenericFieldMetadata(Collections.singleton(item));
|
||||
} else {
|
||||
fieldDescription.setGenericFieldMetadata(getClassFieldDescription(actualTypeArgument));
|
||||
}
|
||||
|
||||
} else if (Collection.class.isAssignableFrom(declaredFieldType)) {
|
||||
// 如果是泛型类型,遍历泛泛型的class类型里的字段
|
||||
Class<?> genericClass = TypeUtil.getClass(TypeUtil.getTypeArgument(TypeUtil.getType(declaredField)));
|
||||
if (BaseRequest.class.isAssignableFrom(genericClass)) {
|
||||
fieldDescription.setGenericFieldMetadata(getClassFieldDescription(genericClass));
|
||||
}
|
||||
}
|
||||
|
||||
// 获取字段的所有注解
|
||||
Annotation[] annotations = declaredField.getAnnotations();
|
||||
if (annotations != null && annotations.length > 0) {
|
||||
|
||||
// 设置字段的所有注解
|
||||
fieldDescription.setAnnotations(annotationsToStrings(annotations));
|
||||
|
||||
// 遍历字段上的所有注解,找到带groups属性的,按group分类组装注解
|
||||
Map<String, Set<String>> groupAnnotations = new HashMap<>();
|
||||
for (Annotation annotation : annotations) {
|
||||
Class<?>[] validateGroupsClasses = invokeAnnotationMethodIgnoreError(annotation, "groups", Class[].class);
|
||||
if (validateGroupsClasses != null) {
|
||||
for (Class<?> validateGroupsClass : validateGroupsClasses) {
|
||||
addGroupValidateAnnotation(annotation, validateGroupsClass, groupAnnotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置分组注解
|
||||
fieldDescription.setGroupValidationMessage(groupAnnotations);
|
||||
|
||||
// 填充字段的中文名称
|
||||
ChineseDescription chineseDescription = declaredField.getAnnotation(ChineseDescription.class);
|
||||
if (chineseDescription != null) {
|
||||
fieldDescription.setChineseName(chineseDescription.value());
|
||||
}
|
||||
}
|
||||
return fieldDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用注解上的某个方法,并获取结果,忽略异常
|
||||
*
|
||||
|
|
|
@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
|
|||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 接口字段信息封装类
|
||||
|
@ -64,6 +65,11 @@ public class ApiResourceFieldRequest extends BaseRequest {
|
|||
*/
|
||||
private String fieldValidationMsg;
|
||||
|
||||
/**
|
||||
* 字段子字段信息(Object和List会用到)
|
||||
*/
|
||||
private Set<ApiResourceFieldRequest> children;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
|
|
|
@ -2,6 +2,7 @@ package cn.stylefeng.roses.kernel.system.modular.resource.entity;
|
|||
|
||||
import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity;
|
||||
import cn.stylefeng.roses.kernel.scanner.api.annotation.field.ChineseDescription;
|
||||
import cn.stylefeng.roses.kernel.system.api.pojo.resource.ApiResourceFieldRequest;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
|
@ -115,6 +116,6 @@ public class ApiResource extends BaseEntity {
|
|||
*/
|
||||
@TableField(exist = false)
|
||||
@ChineseDescription("该资源所有字段")
|
||||
private List<ApiResourceField> apiResourceFieldList;
|
||||
private List<ApiResourceFieldRequest> apiResourceFieldList;
|
||||
|
||||
}
|
|
@ -58,7 +58,7 @@ public class ApiResourceField extends BaseEntity {
|
|||
private String fieldCode;
|
||||
|
||||
/**
|
||||
* 字段类型:string或file
|
||||
* 字段类型:string或file、List、Object
|
||||
*/
|
||||
@TableField("field_type")
|
||||
@ChineseDescription("字段类型")
|
||||
|
@ -78,6 +78,13 @@ public class ApiResourceField extends BaseEntity {
|
|||
@ChineseDescription("字段其他校验信息,后端校验注解内容")
|
||||
private String fieldValidationMsg;
|
||||
|
||||
/**
|
||||
* 字段子字段信息(Object和List会用到)
|
||||
*/
|
||||
@TableField("field_sub_info")
|
||||
@ChineseDescription("字段子字段信息(Object和List会用到)")
|
||||
private String fieldSubInfo;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
|
|
|
@ -2,6 +2,7 @@ package cn.stylefeng.roses.kernel.system.modular.resource.service;
|
|||
|
||||
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
|
||||
import cn.stylefeng.roses.kernel.system.api.pojo.resource.ApiGroupRequest;
|
||||
import cn.stylefeng.roses.kernel.system.api.pojo.resource.ApiResourceFieldRequest;
|
||||
import cn.stylefeng.roses.kernel.system.api.pojo.resource.ApiResourceRequest;
|
||||
import cn.stylefeng.roses.kernel.system.modular.resource.entity.ApiResource;
|
||||
import cn.stylefeng.roses.kernel.system.modular.resource.entity.ApiResourceField;
|
||||
|
@ -87,7 +88,7 @@ public interface ApiResourceService extends IService<ApiResource> {
|
|||
* @author majianguo
|
||||
* @date 2021/5/24 下午6:45
|
||||
**/
|
||||
List<ApiResourceField> allField(ApiResourceRequest apiResourceRequest);
|
||||
List<ApiResourceFieldRequest> allField(ApiResourceRequest apiResourceRequest);
|
||||
|
||||
/**
|
||||
* 重置
|
||||
|
|
|
@ -29,6 +29,7 @@ import cn.stylefeng.roses.kernel.system.modular.resource.service.SysResourceServ
|
|||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
@ -38,10 +39,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -221,7 +219,16 @@ public class ApiResourceServiceImpl extends ServiceImpl<ApiResourceMapper, ApiRe
|
|||
List<ApiResourceField> apiResourceFields = this.apiResourceFieldService.list(apiResourceFieldLambdaQueryWrapper);
|
||||
// 过滤创建时间和创建人
|
||||
apiResourceFields.removeIf(resourceField -> "createTime".equalsIgnoreCase(resourceField.getFieldCode()) || "createUser".equalsIgnoreCase(resourceField.getFieldCode()) || "updateTime".equalsIgnoreCase(resourceField.getFieldCode()) || "updateUser".equalsIgnoreCase(resourceField.getFieldCode()));
|
||||
apiResource.setApiResourceFieldList(apiResourceFields);
|
||||
|
||||
List<ApiResourceFieldRequest> apiResourceFieldList = new ArrayList<>();
|
||||
for (ApiResourceField apiResourceField : apiResourceFields) {
|
||||
// 转换为前端对象
|
||||
ApiResourceFieldRequest apiResourceFieldRequest = BeanUtil.toBean(apiResourceField, ApiResourceFieldRequest.class);
|
||||
apiResourceFieldRequest.setChildren(JSON.parseObject(apiResourceField.getFieldSubInfo(), Set.class, Feature.SupportAutoType));
|
||||
apiResourceFieldList.add(apiResourceFieldRequest);
|
||||
}
|
||||
|
||||
apiResource.setApiResourceFieldList(apiResourceFieldList);
|
||||
|
||||
return apiResource;
|
||||
}
|
||||
|
@ -282,7 +289,7 @@ public class ApiResourceServiceImpl extends ServiceImpl<ApiResourceMapper, ApiRe
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ApiResourceField> allField(ApiResourceRequest apiResourceRequest) {
|
||||
public List<ApiResourceFieldRequest> allField(ApiResourceRequest apiResourceRequest) {
|
||||
LambdaQueryWrapper<SysResource> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
sysResourceLambdaQueryWrapper.eq(SysResource::getResourceCode, apiResourceRequest.getResourceCode());
|
||||
SysResource sysResources = sysResourceService.getOne(sysResourceLambdaQueryWrapper);
|
||||
|
@ -291,20 +298,28 @@ public class ApiResourceServiceImpl extends ServiceImpl<ApiResourceMapper, ApiRe
|
|||
ResourceDefinition fillResourceDetail = ResourceFactory.fillResourceDetail(ResourceFactory.createResourceDefinition(sysResources));
|
||||
|
||||
// 把所有字段加进去
|
||||
List<ApiResourceField> apiResourceFieldList = new ArrayList<>();
|
||||
List<ApiResourceFieldRequest> apiResourceFieldList = new ArrayList<>();
|
||||
if (ObjectUtil.isNotEmpty(fillResourceDetail.getParamFieldDescriptions())) {
|
||||
// 处理所有请求字段
|
||||
for (FieldMetadata fieldMetadata : fillResourceDetail.getParamFieldDescriptions()) {
|
||||
ApiResourceField conversion = this.conversion(sysResources, null, fieldMetadata);
|
||||
conversion.setFieldLocation("request");
|
||||
apiResourceFieldList.add(conversion);
|
||||
|
||||
// 转换为前端对象
|
||||
ApiResourceFieldRequest apiResourceFieldRequest = BeanUtil.toBean(conversion, ApiResourceFieldRequest.class);
|
||||
apiResourceFieldRequest.setChildren(JSON.parseObject(conversion.getFieldSubInfo(), Set.class, Feature.SupportAutoType));
|
||||
apiResourceFieldList.add(apiResourceFieldRequest);
|
||||
}
|
||||
|
||||
// 处理所有响应字段
|
||||
for (FieldMetadata fieldDescription : fillResourceDetail.getResponseFieldDescriptions()) {
|
||||
ApiResourceField conversion = this.conversion(sysResources, null, fieldDescription);
|
||||
conversion.setFieldLocation("response");
|
||||
apiResourceFieldList.add(conversion);
|
||||
|
||||
// 转换为前端对象
|
||||
ApiResourceFieldRequest apiResourceFieldRequest = BeanUtil.toBean(conversion, ApiResourceFieldRequest.class);
|
||||
apiResourceFieldRequest.setChildren(JSON.parseObject(conversion.getFieldSubInfo(), Set.class, Feature.SupportAutoType));
|
||||
apiResourceFieldList.add(apiResourceFieldRequest);
|
||||
}
|
||||
}
|
||||
return apiResourceFieldList;
|
||||
|
@ -400,7 +415,11 @@ public class ApiResourceServiceImpl extends ServiceImpl<ApiResourceMapper, ApiRe
|
|||
item.setApiResourceId(apiResourceId);
|
||||
item.setFieldCode(fieldMetadata.getFieldName());
|
||||
item.setFieldName(fieldMetadata.getChineseName());
|
||||
if ("file".equalsIgnoreCase(fieldMetadata.getFieldClassType())) {
|
||||
if ("cn.stylefeng.".contains(fieldMetadata.getFieldClassPath())) {
|
||||
item.setFieldType("object");
|
||||
} else if ("java.util".contains(fieldMetadata.getFieldClassPath())) {
|
||||
item.setFieldType("list");
|
||||
} else if ("java.io".contains(fieldMetadata.getFieldClassPath())) {
|
||||
item.setFieldType("file");
|
||||
} else {
|
||||
item.setFieldType("string");
|
||||
|
@ -412,6 +431,17 @@ public class ApiResourceServiceImpl extends ServiceImpl<ApiResourceMapper, ApiRe
|
|||
// 字段校验消息
|
||||
item.setFieldValidationMsg(fieldMetadata.getValidationMessages());
|
||||
|
||||
// 如果还有子字段,则处理字段
|
||||
Set<FieldMetadata> genericFieldMetadata = fieldMetadata.getGenericFieldMetadata();
|
||||
if (ObjectUtil.isNotEmpty(genericFieldMetadata)) {
|
||||
Set<ApiResourceField> apiResourceFieldSet = new HashSet<>();
|
||||
for (FieldMetadata genericFieldMetadatum : genericFieldMetadata) {
|
||||
ApiResourceField conversion = this.conversion(sysResource, apiResourceId, genericFieldMetadatum);
|
||||
apiResourceFieldSet.add(conversion);
|
||||
}
|
||||
item.setFieldSubInfo(JSON.toJSONString(apiResourceFieldSet, SerializerFeature.WriteClassName));
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue