对象-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;

    }

}

 

posted @ 2016-10-29 09:24  gulp  阅读(1179)  评论(0编辑  收藏  举报