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 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 getObjectNullFieldName(Object object) { BeanMap beanMap = BeanMap.create(object); List 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 objToMapIgnoreNull(Object obj) { return objToMap(obj, true); } /** * 将对象转换为map * * @param obj 对象 * @return 键值对 */ public static Map objToMap(Object obj) { return objToMap(obj, false); } /** * 将对象转换为map * * @param obj 对象 * @param ignoreNull 忽略空值字段 * @return 键值对 */ private static Map objToMap(Object obj, boolean ignoreNull) { return JSONUtil.parseObj(obj, ignoreNull); } /** * entity 转换 * * @param obj 源对象 * @param clazz 目标类型 * @param 泛型 * @return 目标对象 */ public static T cloneShallow(Object obj, Class clazz) { if (obj == null) { return null; } T t = BeanUtils.instantiateClass(clazz); BeanUtils.copyProperties(obj, t); return t; } /** * entity 集合转换 * * @param collection 源对象集合 * @param clazz 目标类型 * @param 泛型 * @return 目标对象集合 */ public static List cloneShallow(Collection collection, Class clazz) { return collection.stream().map(item -> convert(item, clazz)).collect(Collectors.toList()); } /** * entity 转换 * * @param obj 源对象 * @param clazz 目标类型 * @param 泛型 * @return 目标对象 */ public static T convert(Object obj, Class clazz) { return objectMapper.convertValue(obj, clazz); } public static T convert(Object obj, TypeReference type) { return objectMapper.convertValue(obj, type); } /** * entity 转换 * * @param optional 源对象 * @param clazz 目标类型 * @param 泛型 * @return 目标对象 */ public static T convert(Optional optional, Class clazz) { return optional.map(obj -> convert(obj, clazz)).orElseGet(null); } /** * entity 集合转换 * * @param collection 源对象集合 * @param clazz 目标类型 * @param 泛型 * @return 目标对象集合 */ public static List convert(Collection collection, Class clazz) { return JSONArray.parseArray(JSONArray.toJSONString(collection), clazz); } /** * entity 集合转换 * * @param iterable 实体集合 * @param clazz 目标类型 * @param 泛型 * @return 目标对象集合 */ public static List convert(Iterable iterable, Class clazz) { return convert(StreamSupport.stream(iterable.spliterator(), false), clazz); } /** * entity 集合转换 * * @param stream 实体集合流 * @param clazz 目标类型 * @param 泛型 * @return 目标对象集合 */ public static List convert(Stream stream, Class clazz) { return stream.map(entity -> convert(entity, clazz)).collect(Collectors.toList()); } /** * map 转对象 * * @param clazz 目标类型 * @param collection 键值对集合 * @param 泛型 * @return 目标对象集合 */ public static List mapToObj(Class clazz, Collection> collection) { return collection.stream().map(map -> BeanConverts.mapToObj(clazz, map)).collect(Collectors.toList()); } /** * map 转对象 * * @param clazz 目标类型 * @param map 键值对 * @param 泛型 * @return 目标对象 */ public static T mapToObj(Class clazz, Map 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 泛型 * @return 属性值map */ public static Map propertyToMap(Collection collection, String keyProperty, String valueProperty) { Map 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 objToMapNonJson(Object obj) { Map 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; } }