package com.moral.api.utils;
|
|
import cn.hutool.json.JSONUtil;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.cglib.beans.BeanMap;
|
|
import java.beans.BeanInfo;
|
import java.beans.IntrospectionException;
|
import java.beans.Introspector;
|
import java.beans.PropertyDescriptor;
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
import java.math.BigDecimal;
|
import java.sql.Timestamp;
|
import java.time.LocalDate;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
import java.util.stream.Stream;
|
import java.util.stream.StreamSupport;
|
|
|
import java.util.*;
|
|
/**
|
* @ClassName BeanConverts
|
* @Description TODO
|
* @Author @lizijie
|
* @Date 2023-09-20 13:41
|
* @Version 1.0
|
*/
|
@Slf4j
|
@SuppressWarnings("unchecked")
|
public class BeanConverts {
|
private static ObjectMapper objectMapper = new ObjectMapper();
|
static{
|
|
//序列化的时候序列对象的所有属性
|
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
|
|
//反序列化的时候如果多了其他属性,不抛出异常
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
//如果是空对象的时候,不抛异常
|
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
|
//属性为null的转换
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
}
|
|
private BeanConverts() {
|
}
|
|
/**
|
* BeanUtils.copyProperties 增强
|
* 拷贝时,source 值为空则不拷贝
|
*
|
* @param source 源数据
|
* @param target 目标数据
|
* @param ignoreProperties 忽略属性
|
*/
|
public static void copyPropertiesIgnoreNull(Object source, Object target, String... ignoreProperties) {
|
Set<String> ignoreSet = new HashSet<>();
|
if (ignoreProperties != null) {
|
ignoreSet.addAll(Arrays.asList(ignoreProperties));
|
}
|
ignoreSet.addAll(getObjectNullFieldName(source));
|
BeanUtils.copyProperties(source, target, ignoreSet.toArray(new String[0]));
|
}
|
|
/**
|
* 获取对象字段值为null 的字段名称集合
|
*
|
* @param object 源数据
|
* @return 字段名称集合
|
*/
|
public static List<String> getObjectNullFieldName(Object object) {
|
BeanMap beanMap = BeanMap.create(object);
|
List<String> fieldNameList = new ArrayList<>();
|
for (Object key : beanMap.keySet()) {
|
if (beanMap.get(key) == null) {
|
fieldNameList.add(key.toString());
|
}
|
}
|
return fieldNameList;
|
}
|
|
/**
|
* 将对象转换为map
|
* 不转换空值字段
|
*
|
* @param obj 对象
|
* @return 键值对
|
*/
|
public static Map<String, Object> objToMapIgnoreNull(Object obj) {
|
return objToMap(obj, true);
|
}
|
|
/**
|
* 将对象转换为map
|
*
|
* @param obj 对象
|
* @return 键值对
|
*/
|
public static Map<String, Object> objToMap(Object obj) {
|
return objToMap(obj, false);
|
}
|
|
/**
|
* 将对象转换为map
|
*
|
* @param obj 对象
|
* @param ignoreNull 忽略空值字段
|
* @return 键值对
|
*/
|
private static Map<String, Object> objToMap(Object obj, boolean ignoreNull) {
|
return JSONUtil.parseObj(obj, ignoreNull);
|
}
|
|
/**
|
* entity 转换
|
*
|
* @param obj 源对象
|
* @param clazz 目标类型
|
* @param <T> 泛型
|
* @return 目标对象
|
*/
|
public static <T> T cloneShallow(Object obj, Class<T> clazz) {
|
if (obj == null) {
|
return null;
|
}
|
T t = BeanUtils.instantiateClass(clazz);
|
BeanUtils.copyProperties(obj, t);
|
return t;
|
}
|
|
/**
|
* entity 集合转换
|
*
|
* @param collection 源对象集合
|
* @param clazz 目标类型
|
* @param <T> 泛型
|
* @return 目标对象集合
|
*/
|
public static <T> List<T> cloneShallow(Collection<?> collection, Class<T> clazz) {
|
return collection.stream().map(item -> convert(item, clazz)).collect(Collectors.toList());
|
}
|
|
/**
|
* entity 转换
|
*
|
* @param obj 源对象
|
* @param clazz 目标类型
|
* @param <T> 泛型
|
* @return 目标对象
|
*/
|
public static <T> T convert(Object obj, Class<T> clazz) {
|
|
return objectMapper.convertValue(obj, clazz);
|
}
|
|
public static <T> T convert(Object obj, TypeReference<T> type) {
|
return objectMapper.convertValue(obj, type);
|
}
|
|
/**
|
* entity 转换
|
*
|
* @param optional 源对象
|
* @param clazz 目标类型
|
* @param <T> 泛型
|
* @return 目标对象
|
*/
|
public static <T> T convert(Optional<?> optional, Class<T> clazz) {
|
return optional.map(obj -> convert(obj, clazz)).orElseGet(null);
|
}
|
|
/**
|
* entity 集合转换
|
*
|
* @param collection 源对象集合
|
* @param clazz 目标类型
|
* @param <T> 泛型
|
* @return 目标对象集合
|
*/
|
public static <T> List<T> convert(Collection<?> collection, Class<T> clazz) {
|
return JSONArray.parseArray(JSONArray.toJSONString(collection), clazz);
|
}
|
|
/**
|
* entity 集合转换
|
*
|
* @param iterable 实体集合
|
* @param clazz 目标类型
|
* @param <T> 泛型
|
* @return 目标对象集合
|
*/
|
public static <T> List<T> convert(Iterable<?> iterable, Class<T> clazz) {
|
return convert(StreamSupport.stream(iterable.spliterator(), false), clazz);
|
}
|
|
/**
|
* entity 集合转换
|
*
|
* @param stream 实体集合流
|
* @param clazz 目标类型
|
* @param <T> 泛型
|
* @return 目标对象集合
|
*/
|
public static <T> List<T> convert(Stream<?> stream, Class<T> clazz) {
|
return stream.map(entity -> convert(entity, clazz)).collect(Collectors.toList());
|
}
|
|
|
/**
|
* map 转对象
|
*
|
* @param clazz 目标类型
|
* @param collection 键值对集合
|
* @param <T> 泛型
|
* @return 目标对象集合
|
*/
|
public static <T> List<T> mapToObj(Class<T> clazz, Collection<Map<String, Object>> collection) {
|
return collection.stream().map(map -> BeanConverts.mapToObj(clazz, map)).collect(Collectors.toList());
|
}
|
|
/**
|
* map 转对象
|
*
|
* @param clazz 目标类型
|
* @param map 键值对
|
* @param <T> 泛型
|
* @return 目标对象
|
*/
|
public static <T> T mapToObj(Class<T> clazz, Map<String, Object> map) {
|
T d = BeanUtils.instantiateClass(clazz);
|
BeanInfo beanInfo;
|
try {
|
beanInfo = Introspector.getBeanInfo(d.getClass());
|
} catch (IntrospectionException e) {
|
log.warn(e.getMessage(), e);
|
return null;
|
}
|
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
for (PropertyDescriptor property : propertyDescriptors) {
|
Method setter = property.getWriteMethod();
|
if (setter == null) {
|
continue;
|
}
|
Object value = map.get(property.getName());
|
if (value == null) {
|
continue;
|
} else if (value instanceof Timestamp) {
|
if (property.getPropertyType().equals(LocalDate.class)) {
|
value = ((Timestamp) value).toLocalDateTime().toLocalDate();
|
} else {
|
value = ((Timestamp) value).toLocalDateTime();
|
}
|
} else if (property.getPropertyType().equals(BigDecimal.class)) {
|
value = BigDecimal.valueOf((double) value);
|
}
|
try {
|
setter.invoke(d, value);
|
} catch (Exception e) {
|
log.warn(e.getMessage(), e);
|
}
|
}
|
return d;
|
}
|
|
/**
|
* 对象集合中取出两个字段,组成map
|
*
|
* @param collection 对象集合
|
* @param keyProperty key属性值
|
* @param valueProperty value属性值
|
* @param <E> 泛型
|
* @return 属性值map
|
*/
|
public static <E> Map<String, E> propertyToMap(Collection collection, String keyProperty, String valueProperty) {
|
Map<String, E> map = new LinkedHashMap<>();
|
if (collection.isEmpty()) {
|
return map;
|
}
|
Object obj = collection.iterator().next();
|
BeanInfo beanInfo;
|
try {
|
beanInfo = Introspector.getBeanInfo(obj.getClass());
|
} catch (IntrospectionException e) {
|
log.warn(e.getMessage(), e);
|
return map;
|
}
|
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
Method keyGetter = null;
|
Method valueGetter = null;
|
for (PropertyDescriptor property : propertyDescriptors) {
|
if (keyProperty.equals(property.getName()) && property.getReadMethod() != null) {
|
keyGetter = property.getReadMethod();
|
} else if (valueProperty.equals(property.getName()) && property.getReadMethod() != null) {
|
valueGetter = property.getReadMethod();
|
}
|
}
|
if (keyGetter == null || valueGetter == null) {
|
return map;
|
}
|
for (Object item : collection) {
|
try {
|
map.put(keyGetter.invoke(item).toString(), (E) valueGetter.invoke(item));
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
log.warn(e.getMessage(), e);
|
}
|
}
|
return map;
|
}
|
|
/**
|
* 将对象转换为map
|
*
|
* @param obj 对象
|
* @return 键值对
|
*/
|
public static Map<String, Object> objToMapNonJson(Object obj) {
|
Map<String, Object> map = new HashMap<>(8);
|
if (obj != null) {
|
BeanMap beanMap = BeanMap.create(obj);
|
for (Object key : beanMap.keySet()) {
|
Object value = beanMap.get(key);
|
map.put(key.toString(), value);
|
}
|
}
|
return map;
|
}
|
}
|