需求
需要将Object对象里面的属性和值转化成Map对象,包括嵌套类型,这里我是往已有的map赋值
工具类
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Auther: wxy
* @Date: 2020/10/21 16:45
* @Description:
*/
public class ReflectUtils {
/**
* 将Object对象里面的属性和值转化成Map对象
*
* @param obj
* @return
* @throws IllegalAccessException
*/
public static Map objectToMap(Object obj, Map<String, String> map) throws IllegalAccessException {
Assert.notNull(map, "map不能为空");
Class<?> clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
Class<?> fieldType = field.getType();
MyObjToMapAnnotation annotation = field.getAnnotation(MyObjToMapAnnotation.class);
Object value = field.get(obj);
//判断是否必传
if (annotation != null) {
//是否必传
boolean b = annotation.isNotNull();
//别名
String name = annotation.name();
String connector = annotation.connector();
//是否使用别名
boolean useAlias = false;
if (StringUtils.isNotBlank(name)) {
useAlias = true;
}
if (value == null) {
//必传且值为空 todo 必传校验
if (b) {
throw new RuntimeException((useAlias ? name : fieldName) + "为必传字段");
}
//值不为空
} else {
//判断类型
if (fieldType.isPrimitive() || isPackageType(fieldType) || (String.class == fieldType)) {
map.put((useAlias ? name : fieldName), value.toString());
//是否list类型或者其子类
} else if (fieldType.isAssignableFrom(List.class)) {
//得到泛型类型
Type gt = field.getGenericType();
if (!(gt instanceof ParameterizedType)) {
throw new RuntimeException("集合需指定泛型");
}
ParameterizedType pt = (ParameterizedType) gt;
//获取泛型类的第一个参数
Class aClass = (Class) pt.getActualTypeArguments()[0];
List list = (List) field.get(obj);
//泛型是普通的包装类和String
if (isPackageType(aClass) || (String.class == aClass)) {
//是否有连接符
if (StringUtils.isNotBlank(connector)) {
String collect = (String) list.stream().map(String::valueOf).collect(Collectors.joining(connector));
map.put((useAlias ? name : fieldName), collect);
} else {
map.put((useAlias ? name : fieldName), JSONObject.toJSONString(list));
}
} else {
//自定义嵌套类型
List<Map> items = new ArrayList<>();
for (Object o : list) {
//递归针对嵌套
//这里要用深克隆
Map item = objectToMap(o, JSONObject.parseObject( JSONObject.toJSONString(map),Map.class));
items.add(item);
}
map.put((useAlias ? name : fieldName), JSONObject.toJSONString(items));
}
}
}
} else {
if (value != null) {
//判断类型
if (fieldType.isPrimitive() || isPackageType(fieldType) || (String.class == fieldType)) {
map.put(fieldName, value.toString());
//是否list类型或者其子类
} else if (fieldType.isAssignableFrom(List.class)) {
//得到泛型类型
Type gt = field.getGenericType();
if (!(gt instanceof ParameterizedType)) {
throw new RuntimeException("集合参数需要指定泛型");
}
//获取泛型类的第一个参数
ParameterizedType pt = (ParameterizedType) gt;
Class aClass = (Class) pt.getActualTypeArguments()[0];
List list = (List) field.get(obj);
//泛型是普通的包装类和String
if (isPackageType(aClass) || (String.class == aClass)) {
//是否有连接符
map.put(fieldName, JSONObject.toJSONString(list));
} else {
//自定义嵌套类型
List<Map> items = new ArrayList<>();
for (Object o : list) {
//这里要用深克隆
Map item = objectToMap(o, JSONObject.parseObject( JSONObject.toJSONString(map),Map.class));
items.add(item);
}
map.put(fieldName, JSONObject.toJSONString(items));
}
}
}
}
}
return map;
}
/**
* 是否包装类型
*
* @param clazz
* @return
*/
private static boolean isPackageType(Class clazz) {
boolean flag = false;
if (clazz == Integer.class) {
flag = true;
} else if (clazz == Byte.class) {
flag = true;
} else if (clazz == Short.class) {
flag = true;
} else if (clazz == Float.class) {
flag = true;
} else if (clazz == Double.class) {
flag = true;
} else if (clazz == Character.class) {
flag = true;
} else if (clazz == Long.class) {
flag = true;
} else if (clazz == Boolean.class) {
flag = true;
}
return flag;
}
}
自定义注解
import java.lang.annotation.*;
/**
* @Auther: wxy
* @Date: 2020/10/21 15:50
* @Description:
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyObjToMapAnnotation {
/**
* 不为空
* @return
*/
boolean isNotNull() default false;
/**
* 别名
* @return
*/
String name() default "";
/**
* list类型才有用
* @return
*/
String connector()default "";
}