package com.sgcc.utils; import com.google.common.collect.Maps; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; /** * 实体转化工具类 * * @author zhaoyuanyuan * @version 1.0.0 * @date 2024/06/24 17:35 */ @Slf4j public class BeanUtils { private static final String CLASS = "class"; private BeanUtils() { throw new IllegalStateException("Utility class"); } /** * 判断对象是否为数字 * * @param o * @return */ public static boolean isNumber(Object o) { if (o == null) { return false; } if (o instanceof Number) { return true; } if (o instanceof String) { try { Double.parseDouble((String) o); return true; } catch (NumberFormatException e) { return false; } } return false; } /** * 将bean转化为map * * @param clazz bean * @param 泛型 * @return Map 返回对象 */ public static Map toMap(final T clazz) { Map paramsMap = Maps.newHashMap(); try { BeanInfo bi = Introspector.getBeanInfo(clazz.getClass()); PropertyDescriptor[] pd = bi.getPropertyDescriptors(); for (int i = 0; i < pd.length; i++) { String name = pd[i].getName(); Method method = pd[i].getReadMethod(); Object value = method.invoke(clazz); if (!CLASS.equals(name)) { paramsMap.put(name, value); } } } catch (IntrospectionException ie) { log.error("IntrospectionException.className=" + clazz.getClass() + "BeanInfo error : ", ie); } catch (Exception e) { log.error("Exception.className=" + clazz.getClass() + "Method error :", e); } return paramsMap; } /** * 获取到对象中属性为指定值的属性名 * * @param source 要拷贝的对象 * @param values 指定的值数组 * @return */ public static String[] getPropertyNamesWithValues(Object source, String... values) { List valueList = (values != null ? Arrays.asList(values) : null); final BeanWrapper src = new BeanWrapperImpl(source); PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set propertyNames = new HashSet<>(); for (PropertyDescriptor pd : pds) { Object srcValue = src.getPropertyValue(pd.getName()); if (valueList == null && srcValue == null) { propertyNames.add(pd.getName()); } else if (valueList != null && valueList.contains(srcValue)) { propertyNames.add(pd.getName()); } else { // DO NOTHING } } String[] result = new String[propertyNames.size()]; return propertyNames.toArray(result); } /** * 列表实体类属性拷贝,忽略null值 * * @param fromList 待转换实体列数组 * @param tClass 目标类 * @param * @param * @return */ public static List copyPropertiesIgnoreNull(List fromList, Class tClass) { return copyPropertiesIgnoreValues(fromList, tClass, (String[]) null); } /** * 实体类属性拷贝,忽略null值、空字符串""和"null" * * @param fromList 待转换实体列数组 * @param tClass 目标类 * @param * @param * @return */ public static List copyPropertiesIgnoreEmpty(List fromList, Class tClass) { return copyPropertiesIgnoreValues(fromList, tClass, null, "", "null"); } /** * 实体类列表属性拷贝,忽略指定值 * 将entityList转换成modelList * * @param fromList 待转换实体列数组 * @param tClass 目标类 * @param values 指定的值数组 * @param * @param * @return */ public static List copyPropertiesIgnoreValues(List fromList, Class tClass, String... values) { Assert.notNull(tClass, "tClass must not be null."); List tList = new ArrayList<>(); if (fromList != null && !fromList.isEmpty()) { for (F f : fromList) { T t = copyPropertiesIgnoreValues(f, tClass, values); tList.add(t); } } return tList; } /** * 实体类列表属性拷贝 * 将entityList转换成modelList * * @param fromList 待转换实体列数组 * @param tClass 目标类 * @param * @param * @return */ public static List copyProperties(List fromList, Class tClass) { Assert.notNull(tClass, "tClass must not be null."); List tList = new ArrayList<>(); if (fromList != null && !fromList.isEmpty()) { for (F f : fromList) { T t = copyProperties(f, tClass); tList.add(t); } } return tList; } /** * 实体类属性拷贝,忽略null值 * * @param entity 实体类 * @param modelClass 目标类 * @param * @param * @return */ public static T copyPropertiesIgnoreNull(F entity, Class modelClass) { return copyPropertiesIgnoreValues(entity, modelClass, (String[]) null); } /** * 实体类属性拷贝,忽略null值、空字符串""和"null" * * @param entity 实体类 * @param modelClass 目标类 * @param * @param * @return */ public static T copyPropertiesIgnoreEmpty(F entity, Class modelClass) { return copyPropertiesIgnoreValues(entity, modelClass, null, "", "null"); } /** * 实体类属性拷贝,忽略指定值 * * @param entity 实体类 * @param modelClass 目标类 * @param values 指定的值数组 * @param * @param * @return */ public static T copyPropertiesIgnoreValues(F entity, Class modelClass, String... values) { return copyProperties(entity, modelClass, getPropertyNamesWithValues(entity, values)); } /** * 实体类属性拷贝 * * @param entity 实体类 * @param modelClass 目标类 * @param * @param * @return */ public static T copyProperties(F entity, Class modelClass) { return copyProperties(entity, modelClass, (String[]) null); } /** * 实体类属性拷贝 * * @param entity 实体类 * @param modelClass 目标类 * @param ignoreProperties 忽略属性列表 * @param * @param * @return */ public static T copyProperties(F entity, Class modelClass, String... ignoreProperties) { Assert.notNull(modelClass, "modelClass must not be null."); Object model = null; try { model = modelClass.newInstance(); } catch (InstantiationException e) { log.error("copyProperties: InstantiationException", e); } catch (IllegalAccessException e) { log.error("copyProperties: IllegalAccessException", e); } if (entity != null) { org.springframework.beans.BeanUtils.copyProperties(entity, model, ignoreProperties); } else { // DO NOTHING } return (T) model; } /** * 将下划线大写方式命名的字符串转换为驼峰式。 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
* 例如:hello_world->helloWorld * * @param name 转换前的下划线大写方式命名的字符串 * @return 转换后的驼峰式命名的字符串 */ public static String camelName(String name) { StringBuilder result = new StringBuilder(); // 快速检查 if (name == null || name.isEmpty()) { // 没必要转换 return ""; } else if (!name.contains("_")) { // 不含下划线,仅将首字母小写 return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase(); } // 用下划线将原始字符串分割 String[] camels = name.split("_"); for (String camel : camels) { // 跳过原始字符串中开头、结尾的下换线或双重下划线 if (camel.isEmpty()) { continue; } // 处理真正的驼峰片段 if (result.length() == 0) { // 第一个驼峰片段,全部字母都小写 result.append(camel.toLowerCase()); } else { // 其他的驼峰片段,首字母大写 result.append(camel.substring(0, 1).toUpperCase()); result.append(camel.substring(1).toLowerCase()); } } return result.toString(); } /** * 将下划线大写方式命名的字符串转换为驼峰式。 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
* 例如:hello_world,test_id->helloWorld,testId * * @param names 转换前的下划线大写方式命名的字符串 * @return 转换后的驼峰式命名的字符串 */ public static String camelNames(String names) { if (names == null || names.equals("")) { return null; } StringBuilder sb = new StringBuilder(); String[] fs = names.split(","); for (String field : fs) { field = camelName(field); sb.append(field + ","); } String result = sb.toString(); return result.substring(0, result.length() - 1); } /** * 将下划线大写方式命名的字符串转换为驼峰式。 * (首字母写) 如果转换前的下划线大写方式命名的字符串为空, * 则返回空字符串。
* 例如:hello_world->HelloWorld * * @param name 转换前的下划线大写方式命名的字符串 * @return 转换后的驼峰式命名的字符串 */ public static String camelNameCapFirst(String name) { // 转换为首字母小写的驼峰片段 String camel = camelName(name); if (camel == null || camel.length() < 1) { return name; } // 首字母大写 char[] charArray = camel.toCharArray(); charArray[0] -= 32; return String.valueOf(charArray); } /** * 将驼峰命名转化成下划线 * * @param param * @return */ public static String camelToUnderline(String param) { if (param == null) { return null; } int paramLen = param.length(); if (paramLen < 3) { return param.toLowerCase(); } int wordCount = 0; StringBuilder sb = new StringBuilder(param); // 从第三个字符开始 避免命名不规范 for (int i = 2; i < paramLen; i++) { if (Character.isUpperCase(param.charAt(i))) { sb.insert(i + wordCount, "_"); wordCount += 1; } } return sb.toString().toLowerCase(); } /** * 根据指定的类名判定指定的类是否存在。 * * @param className * @return */ public static boolean validClass(String className) { try { Class.forName(className); return true; } catch (ClassNotFoundException e) { return false; } } /** * 判定类是否继承自父类 * * @param cls 子类 * @param parentClass 父类 * @return */ @SuppressWarnings({"unchecked", "rawtypes"}) public static boolean isInherit(Class cls, Class parentClass) { return parentClass.isAssignableFrom(cls); } /** * 输入基类包名,扫描其下的类,返回类的全路径 * * @param basePackages 如:com.hotent * @return * @throws IllegalArgumentException */ @SuppressWarnings("all") public static List scanPackages(String basePackages) throws IllegalArgumentException { ResourcePatternResolver rl = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory( rl); List result = new ArrayList(); String[] arrayPackages = basePackages.split(","); try { for (int j = 0; j < arrayPackages.length; j++) { String packageToScan = arrayPackages[j]; String packagePart = packageToScan.replace('.', '/'); String classPattern = "classpath*:/" + packagePart + "/**/*.class"; Resource[] resources = rl.getResources(classPattern); for (int i = 0; i < resources.length; i++) { Resource resource = resources[i]; MetadataReader metadataReader = metadataReaderFactory .getMetadataReader(resource); String className = metadataReader.getClassMetadata() .getClassName(); result.add(className); } } } catch (Exception e) { new IllegalArgumentException("scan pakcage class error,pakcages:" + basePackages); } return result; } /** * 将字符串数据按照指定的类型进行转换。 * * @param typeName 实际的数据类型 * @param value 字符串值。 * @return Object */ public static Object convertByActType(String typeName, String value) { Object o = null; if (typeName.equals("int")) { o = Integer.parseInt(value); } else if (typeName.equals("short")) { o = Short.parseShort(value); } else if (typeName.equals("long")) { o = Long.parseLong(value); } else if (typeName.equals("float")) { o = Float.parseFloat(value); } else if (typeName.equals("double")) { o = Double.parseDouble(value); } else if (typeName.equals("boolean")) { o = Boolean.parseBoolean(value); } else if (typeName.equals("java.lang.String")) { o = value; } else { o = value; } return o; } /** * 根据类和成员变量名称获取成员变量。 * * @param thisClass * @param fieldName * @return * @throws NoSuchFieldException Field */ public static Field getField(Class thisClass, String fieldName) throws NoSuchFieldException { if (fieldName == null) { throw new NoSuchFieldException("Error field !"); } Field field = thisClass.getDeclaredField(fieldName); return field; } /** * 数据列表去重 * * @param list */ @SuppressWarnings({"rawtypes", "unchecked"}) public static void removeDuplicate(List list) { HashSet h = new HashSet(list); list.clear(); list.addAll(h); } private static void handleReflectionException(Exception e) { ReflectionUtils.handleReflectionException(e); } }