Java利用内省进行Map和JavaBean的互转

最近有一个需求分下来里边涉及到多个地方的Map和JavaBean的互转,要用的地方很少的话我就会原地利用get set进行处理了,但是这次由于涉及的地方多就想着抽个工具类,然后就想起了java的内省,其实原理就是利用反射获取到javaBean的成员属性然后进行相应的操作,活不多说上代码。

/**
 * @Description: 内省进行数据转换
 * @Author: LiuBing
 * @Date: 17:31 2018/8/29
 */
public class DataConvertUtil {

    /**
     * javaBean转map
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map javaBeanToMap(Object obj) throws Exception{
        Map map =new HashMap<>();
        // 获取javaBean的BeanInfo对象
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(),Object.class);
        // 获取属性描述器
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            // 获取属性名
            String key = propertyDescriptor.getName();
            // 获取该属性的值
            Method readMethod = propertyDescriptor.getReadMethod();
            // 通过反射来调用javaBean定义的getName()方法
            Object value = readMethod.invoke(obj);
            map.put(key, value);
        }
        return map;
    }

里边涉及到几个重要的Api,BeanInfo,PropertyDescriptor等等,代码里边注释也很明确。

    /**
     * map转javaBean
     * @param map
     * @param clazz
     * @param 
     * @return
     * @throws Exception
     */
    public static T mapToJavaBean(Map map , Class clazz) throws Exception{
        // new 出一个对象
        T obj = clazz.newInstance();
        // 获取javaBean的BeanInfo对象
        BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
        // 获取属性描述器
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            // 获取属性名
            String key = propertyDescriptor.getName();
            Object value = map.get(key);
            Method writeMethod = propertyDescriptor.getWriteMethod();
            if (map.containsKey(key)){
                // 解决 argument type mismatch 的问题,转换成对应的javaBean属性类型
                String typeName = propertyDescriptor.getPropertyType().getTypeName();
                // System.out.println(key +"<==>"+ typeName);
                if ("java.lang.Integer".equals(typeName)){
                    value = Integer.parseInt(value.toString());
                }
                if ("java.lang.Long".equals(typeName)){
                    value = Long.parseLong(value.toString());
                }
                if ("java.util.Date".equals(typeName)){
                    value = new SimpleDateFormat("yyyy-MM-dd").parse(value.toString());
                }
            }
            // 通过反射来调用javaBean定义的setName()方法
            writeMethod.invoke(obj,value);
        }
        return obj;
    }

这里我在测试的时候遇到一个问题,也就是注释中argument type mismatch的问题,为什么呢,因为前段给我传过来的数据都是以表单形式进来的,到服务端就都是字符串的类型了,所以这块做了统一处理:根据javaBean常用的数据类型做了对应匹配,为的是将字符串转换为对应的javaBean属性类型,这里小小的优化可以将多个if判断换成switch case会好一点,对于时间Date类型的属性的格式也可以做成灵活可配置的而不必写死,ok,今天就到这。

你可能感兴趣的:(Java利用内省进行Map和JavaBean的互转)