对象-Map 相互转换
package org.scivf.common.map; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.sql.SQLException; import java.sql.Timestamp; import java.util.HashMap; import java.util.Map; import org.springframework.beans.BeanUtils; public class MapUtils { /** * 把指定的复杂对象属性,按照指定的内容,封装到新的map中 * * @param source * 目标对象 * @param ps * 需要封装到map中的属性 * @return */ public static Map<String, Object> obj2map(Object source, String[] ps) { Map<String, Object> map = new HashMap<>(); if (source == null) return null; if (ps == null || ps.length < 1) { return null; } for (String p : ps) { PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), p); if (sourcePd != null && sourcePd.getReadMethod() != null) { try { Method readMethod = sourcePd.getReadMethod(); if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { readMethod.setAccessible(true); } Object value = readMethod.invoke(source, new Object[0]); map.put(p, value); } catch (Exception ex) { throw new RuntimeException("Could not copy properties from source to target", ex); } } } return map; } public static <T> T map2Bean(Class<T> clazz, Map<String, Object> map) { T newInstance = null; try { newInstance = clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); for (Map.Entry<String, Object> entry : map.entrySet()) { Object value = entry.getValue(); String key = entry.getKey(); for (Field field : fields) { String fieldName = field.getName(); Class<?> fieldType = field.getType(); if (fieldName.toLowerCase().equals(key.toLowerCase())) { value = processColumn(value, fieldType); callSetter(newInstance, fieldName, fieldType, value); break; } } } } catch (Exception e) { e.printStackTrace(); } return newInstance; } protected static Object processColumn(Object value, Class<?> propType) throws SQLException { if (!propType.isPrimitive() && isNull(value)) { return null; } if (propType.equals(String.class)) { return String.valueOf(value); } else if (propType.equals(Integer.TYPE) || propType.equals(Integer.class)) { return (Integer) value; } else if (propType.equals(Boolean.TYPE) || propType.equals(Boolean.class)) { return (Boolean) value; } else if (propType.equals(Long.TYPE) || propType.equals(Long.class)) { return (Long) value; } else if (propType.equals(Double.TYPE) || propType.equals(Double.class)) { return Double.valueOf(value.toString()); } else if (propType.equals(Float.TYPE) || propType.equals(Float.class)) { return Float.valueOf(value.toString()); } else if (propType.equals(Short.TYPE) || propType.equals(Short.class)) { return Short.valueOf(value.toString()); } else if (propType.equals(Byte.TYPE) || propType.equals(Byte.class)) { return Byte.valueOf(value.toString()); } else if (propType.equals(Timestamp.class)) { return new java.sql.Timestamp(((java.util.Date) value).getTime()); } else { return value; } } private static boolean isNull(Object obj) { return (obj == null || "null".equals(obj.toString().trim()) || "".equals(obj.toString().trim())); } private static void callSetter(Object target, String fieldName, Class<?> fieldType, Object value) throws SQLException, NoSuchMethodException, SecurityException { String setMethod = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method setter = target.getClass().getMethod(setMethod, fieldType); if (setter == null) { return; } Class<?>[] params = setter.getParameterTypes(); try { // convert types for some popular ones if (value instanceof java.util.Date) { final String targetType = params[0].getName(); if ("java.sql.Date".equals(targetType)) { value = new java.sql.Date(((java.util.Date) value).getTime()); } else if ("java.sql.Time".equals(targetType)) { value = new java.sql.Time(((java.util.Date) value).getTime()); } else if ("java.sql.Timestamp".equals(targetType)) { value = new java.sql.Timestamp(((java.util.Date) value).getTime()); } } // Don't call setter if the value object isn't the right type if (isCompatibleType(value, params[0])) { setter.invoke(target, new Object[] { value }); } else { throw new SQLException("Cannot set " + fieldName + ": incompatible types, cannot convert " + value.getClass().getName() + " to " + params[0].getName()); // value cannot be null here because isCompatibleType allows null } } catch (IllegalArgumentException e) { throw new SQLException("Cannot set " + fieldName + ": " + e.getMessage()); } catch (IllegalAccessException e) { throw new SQLException("Cannot set " + fieldName + ": " + e.getMessage()); } catch (InvocationTargetException e) { throw new SQLException("Cannot set " + fieldName + ": " + e.getMessage()); } } private static boolean isCompatibleType(Object value, Class<?> type) { // Do object check first, then primitives if (value == null || type.isInstance(value)) { return true; } else if (type.equals(Integer.TYPE) && Integer.class.isInstance(value)) { return true; } else if (type.equals(Long.TYPE) && Long.class.isInstance(value)) { return true; } else if (type.equals(Double.TYPE) && Double.class.isInstance(value)) { return true; } else if (type.equals(Float.TYPE) && Float.class.isInstance(value)) { return true; } else if (type.equals(Short.TYPE) && Short.class.isInstance(value)) { return true; } else if (type.equals(Byte.TYPE) && Byte.class.isInstance(value)) { return true; } else if (type.equals(Character.TYPE) && Character.class.isInstance(value)) { return true; } else if (type.equals(Boolean.TYPE) && Boolean.class.isInstance(value)) { return true; } return false; } }