mirror of https://gitee.com/stylefeng/roses
【7.1.6】FieldMetadata增加一个请求参数类型,为param参数或json参数
parent
21db6a35b8
commit
edff7ec690
|
@ -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 {
|
||||
|
||||
/**
|
||||
* 第一个key是唯一id,用来标识针对某一次的类元数据解析
|
||||
* 第一个key是唯一id,第二个key是当前context下解析过的实体类,用来标识针对某一次的类元数据解析
|
||||
*/
|
||||
public static ConcurrentHashMap<String, Set<String>> META_DATA_CLASS_COUNT_CONTEXT = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 第一个key是唯一id,第二个key是当前context下处理的参数类型
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* Guns采用APACHE 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 param参数,请求是json传来的
|
||||
*/
|
||||
REQUEST_BODY(2);
|
||||
|
||||
ParamTypeEnum(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
private final Integer code;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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类型的字段的描述
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* Guns采用APACHE 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 {
|
||||
|
||||
/**
|
||||
* 请求参数类型,param参数还是request body参数
|
||||
*/
|
||||
private ParamTypeEnum paramTypeEnum;
|
||||
|
||||
/**
|
||||
* 请求参数的所有注解
|
||||
*/
|
||||
private Annotation[] annotations;
|
||||
|
||||
/**
|
||||
* 参数的类型
|
||||
*/
|
||||
private Type parameterizedType;
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数上的注解判断出是param参数还是request 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue