【7.1.6】FieldMetadata增加一个请求参数类型,为param参数或json参数

pull/25/MERGE
fengshuonan 2022-01-20 14:05:11 +08:00
parent 21db6a35b8
commit edff7ec690
10 changed files with 243 additions and 14 deletions

View File

@ -2,6 +2,7 @@ package cn.stylefeng.roses.kernel.scanner.api.context;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.enums.ParamTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassTypeUtil;
import java.lang.reflect.ParameterizedType;
@ -21,10 +22,15 @@ import java.util.concurrent.ConcurrentHashMap;
public class MetadataContext {
/**
* keyid
* keyidkeycontext
*/
public static ConcurrentHashMap<String, Set<String>> META_DATA_CLASS_COUNT_CONTEXT = new ConcurrentHashMap<>();
/**
* keyidkeycontext
*/
public static ConcurrentHashMap<String, ParamTypeEnum> META_DATA_PARAM_TYPE_CONTEXT = new ConcurrentHashMap<>();
/**
*
*
@ -88,6 +94,26 @@ public class MetadataContext {
return false;
}
/**
*
*
* @author fengshuonan
* @date 2022/1/20 13:50
*/
public static void addParamTypeMetadata(String uuid, ParamTypeEnum paramTypeEnum) {
META_DATA_PARAM_TYPE_CONTEXT.put(uuid, paramTypeEnum);
}
/**
*
*
* @author fengshuonan
* @date 2022/1/20 13:50
*/
public static ParamTypeEnum getParamTypeMetadata(String uuid) {
return META_DATA_PARAM_TYPE_CONTEXT.get(uuid);
}
/**
*
*
@ -96,6 +122,7 @@ public class MetadataContext {
*/
public static void cleanContext() {
META_DATA_CLASS_COUNT_CONTEXT.clear();
META_DATA_PARAM_TYPE_CONTEXT.clear();
}
/**
@ -109,6 +136,7 @@ public class MetadataContext {
return;
}
META_DATA_CLASS_COUNT_CONTEXT.remove(uuid);
META_DATA_PARAM_TYPE_CONTEXT.remove(uuid);
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.scanner.api.enums;
import lombok.Getter;
/**
*
*
* @author fengshuonan
* @date 2022/1/20 11:32
*/
@Getter
public enum ParamTypeEnum {
/**
* query param?field1=aaa&field2=bbb
*/
QUERY_PARAM(1),
/**
* body paramjson
*/
REQUEST_BODY(2);
ParamTypeEnum(Integer code) {
this.code = code;
}
private final Integer code;
}

View File

@ -49,7 +49,7 @@ public class ClassDetailMetadataFactory {
// 如果是简单数组类型,则描述一下这个基本类型的信息
Class<?> baseArrayFieldClazz = (Class<?>) fieldType;
Class<?> baseArrayComponentType = baseArrayFieldClazz.getComponentType();
FieldMetadata baseMetadata = ClassDescriptionUtil.createClassMetadata(baseArrayComponentType, FieldTypeEnum.BASIC);
FieldMetadata baseMetadata = ClassDescriptionUtil.createClassMetadata(baseArrayComponentType, FieldTypeEnum.BASIC, uuid);
fieldMetadata = new LinkedHashSet<>();
fieldMetadata.add(baseMetadata);
break;
@ -61,7 +61,7 @@ public class ClassDetailMetadataFactory {
break;
case BASE_COLLECTION:
// 如果是基础集合因为不确定集合的内容所以使用Object来描述一下集合的具体内容
FieldMetadata collectionFieldMetadata = ClassDescriptionUtil.createClassMetadata(Object.class, FieldTypeEnum.OBJECT);
FieldMetadata collectionFieldMetadata = ClassDescriptionUtil.createClassMetadata(Object.class, FieldTypeEnum.OBJECT, uuid);
fieldMetadata = new LinkedHashSet<>();
fieldMetadata.add(collectionFieldMetadata);
break;

View File

@ -41,7 +41,7 @@ public class ClassMetadataFactory {
Class<?> clazz = (Class<?>) type;
// 创建类型的基本信息
fieldMetadata = ClassDescriptionUtil.createClassMetadata(clazz, classFieldType);
fieldMetadata = ClassDescriptionUtil.createClassMetadata(clazz, classFieldType, uuid);
// 补充类型的子信息
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(clazz, uuid);
@ -53,7 +53,7 @@ public class ClassMetadataFactory {
ParameterizedType parameterizedType = (ParameterizedType) type;
// 创建类型的基本信息
fieldMetadata = ClassDescriptionUtil.createParameterizedMetadata(parameterizedType, classFieldType);
fieldMetadata = ClassDescriptionUtil.createParameterizedMetadata(parameterizedType, classFieldType, uuid);
// 补充类型的子信息
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(type, uuid);

View File

@ -99,11 +99,17 @@ public class FieldMetadata {
private Integer genericFieldMetadataType;
/**
* 1-2-3-4-
* FieldTypeEnum
*/
@ChineseDescription("字段类型:1-基本类型2-数组3-实体对象4-其他")
@ChineseDescription("字段类型:详情在 FieldTypeEnum")
private Integer fieldType;
/**
* ParamTypeEnum
*/
@ChineseDescription("请求参数传值类型,详情在 ParamTypeEnum")
private Integer requestParamType;
/**
* object
*/

View File

@ -0,0 +1,57 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.scanner.api.pojo.resource;
import cn.stylefeng.roses.kernel.scanner.api.enums.ParamTypeEnum;
import lombok.Data;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
/**
*
*
* @author fengshuonan
* @date 2022/1/20 11:46
*/
@Data
public class ParameterMetadata {
/**
* ,paramrequest body
*/
private ParamTypeEnum paramTypeEnum;
/**
*
*/
private Annotation[] annotations;
/**
*
*/
private Type parameterizedType;
}

View File

@ -1,8 +1,10 @@
package cn.stylefeng.roses.kernel.scanner.api.util;
import cn.hutool.core.util.IdUtil;
import cn.stylefeng.roses.kernel.scanner.api.context.MetadataContext;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldMetadataTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.enums.ParamTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
import java.lang.reflect.ParameterizedType;
@ -21,7 +23,7 @@ public class ClassDescriptionUtil {
* @author fengshuonan
* @date 2022/1/13 18:06
*/
public static FieldMetadata createClassMetadata(Class<?> clazz, FieldTypeEnum fieldTypeEnum) {
public static FieldMetadata createClassMetadata(Class<?> clazz, FieldTypeEnum fieldTypeEnum, String uuid) {
FieldMetadata fieldMetadataItem = new FieldMetadata();
// 设置唯一id
fieldMetadataItem.setMetadataId(IdUtil.fastSimpleUUID());
@ -37,6 +39,11 @@ public class ClassDescriptionUtil {
fieldMetadataItem.setGenericFieldMetadataType(FieldMetadataTypeEnum.FIELD.getCode());
// 设置字段类型基本、数组、还是object
fieldMetadataItem.setFieldType(fieldTypeEnum.getCode());
// 设置当前context构造的参数类型
ParamTypeEnum paramTypeMetadata = MetadataContext.getParamTypeMetadata(uuid);
if (paramTypeMetadata != null) {
fieldMetadataItem.setRequestParamType(paramTypeMetadata.getCode());
}
// 设置字段
return fieldMetadataItem;
}
@ -47,9 +54,9 @@ public class ClassDescriptionUtil {
* @author fengshuonan
* @date 2022/1/13 18:06
*/
public static FieldMetadata createParameterizedMetadata(ParameterizedType parameterizedType, FieldTypeEnum fieldTypeEnum) {
public static FieldMetadata createParameterizedMetadata(ParameterizedType parameterizedType, FieldTypeEnum fieldTypeEnum, String uuid) {
Class<?> rawType = (Class<?>) parameterizedType.getRawType();
return createClassMetadata(rawType, fieldTypeEnum);
return createClassMetadata(rawType, fieldTypeEnum, uuid);
}
}

View File

@ -2,8 +2,10 @@ package cn.stylefeng.roses.kernel.scanner.api.util;
import cn.hutool.core.util.IdUtil;
import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription;
import cn.stylefeng.roses.kernel.scanner.api.context.MetadataContext;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldMetadataTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.enums.ParamTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.factory.ClassDetailMetadataFactory;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
@ -57,6 +59,11 @@ public class FieldDescriptionUtil {
// 设置字段类型基本、数组、还是object
FieldTypeEnum classFieldType = ClassTypeUtil.getClassFieldType(genericType);
fieldMetadataItem.setFieldType(classFieldType.getCode());
// 设置当前context构造的参数类型
ParamTypeEnum paramTypeMetadata = MetadataContext.getParamTypeMetadata(uuid);
if (paramTypeMetadata != null) {
fieldMetadataItem.setRequestParamType(paramTypeMetadata.getCode());
}
return fieldMetadataItem;
}

View File

@ -25,14 +25,19 @@
package cn.stylefeng.roses.kernel.scanner.api.util;
import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.roses.kernel.scanner.api.enums.ParamTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ParameterMetadata;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@ -153,4 +158,66 @@ public class MethodReflectUtil {
return method.getGenericReturnType();
}
/**
*
*
* @author fengshuonan
* @date 2022/1/20 11:51
*/
public static List<ParameterMetadata> getMethodParameterInfos(Method method) {
List<ParameterMetadata> result = new LinkedList<>();
if (method == null) {
return result;
}
Parameter[] parameters = method.getParameters();
if (parameters.length == 0) {
return result;
}
for (Parameter parameter : parameters) {
ParameterMetadata parameterMetadata = new ParameterMetadata();
// 设置type类型
Type parameterizedType = parameterMetadata.getParameterizedType();
parameterMetadata.setParameterizedType(parameterizedType);
// 设置注解
Annotation[] annotations = parameter.getAnnotations();
parameterMetadata.setAnnotations(annotations);
// 设置参数是param参数还是request body参数
parameterMetadata.setParamTypeEnum(getParamTypeEnum(annotations));
result.add(parameterMetadata);
}
return result;
}
/**
* paramrequest body
*
* @author fengshuonan
* @date 2022/1/20 13:43
*/
public static ParamTypeEnum getParamTypeEnum(Annotation[] annotations) {
// 注解为空直接判断为param参数
if (annotations == null || annotations.length == 0) {
return ParamTypeEnum.QUERY_PARAM;
}
// 如果注解中包含@RequestBody注解则是json请求
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(RequestBody.class)) {
return ParamTypeEnum.REQUEST_BODY;
}
}
// 其他情况判定为时param参数
return ParamTypeEnum.QUERY_PARAM;
}
}

View File

@ -39,6 +39,7 @@ import cn.stylefeng.roses.kernel.scanner.api.exception.ScannerException;
import cn.stylefeng.roses.kernel.scanner.api.factory.ClassMetadataFactory;
import cn.stylefeng.roses.kernel.scanner.api.holder.IpAddrHolder;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ParameterMetadata;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ResourceDefinition;
import cn.stylefeng.roses.kernel.scanner.api.pojo.scanner.ScannerProperties;
import cn.stylefeng.roses.kernel.scanner.api.util.MethodReflectUtil;
@ -302,12 +303,14 @@ public class ApiResourceScanner implements BeanPostProcessor {
MetadataContext.cleanContext(processReturnTypeUuid);
// 填充方法的请求参数字段的详细信息
Type[] methodGenericTypes = MethodReflectUtil.getMethodGenericTypes(method);
if (methodGenericTypes.length > 0) {
List<ParameterMetadata> methodParameterInfos = MethodReflectUtil.getMethodParameterInfos(method);
if (methodParameterInfos.size() > 0) {
LinkedHashSet<FieldMetadata> fieldMetadataLinkedHashSet = new LinkedHashSet<>();
for (Type methodGenericType : methodGenericTypes) {
for (ParameterMetadata parameterMetadata : methodParameterInfos) {
String parameterContextUuid = RandomUtil.randomString(32);
fieldMetadataLinkedHashSet.add(ClassMetadataFactory.beginCreateFieldMetadata(methodGenericType, parameterContextUuid));
// 将当前参数的类型加到context中后边会用到
MetadataContext.addParamTypeMetadata(parameterContextUuid, parameterMetadata.getParamTypeEnum());
fieldMetadataLinkedHashSet.add(ClassMetadataFactory.beginCreateFieldMetadata(parameterMetadata.getParameterizedType(), parameterContextUuid));
MetadataContext.cleanContext(parameterContextUuid);
}
resourceDefinition.setParamFieldDescriptions(fieldMetadataLinkedHashSet);