通过GSON解析复杂json数据(二)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/JacXuan/article/details/77074040

这里我们依旧用上文中的 json 字符串 , 由于转换为 map 依旧需要 javaBean , 所有我们的实体对象也不发生改变
这里我们需要活用 java 反射和类型对比实现需求

先看代码

package com.jacx.test.test01.jsonutil;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;




/**
 * @author 刘合炎
 * @description json对象转java对象
 * 此方法使用方法较为驳杂,请结合例子参考  -- JSONTest
 */
public class TestJsonUtil {

    /**
     * 获得对象的属性和集合中的属性
     * @param clazz
     * @return
     */
    private static List<Field> findFiledsAttr(Class clazz){
        Field[] fields = null;
        List fieldList = new ArrayList();

        while(true){
            if(clazz == null){
                break;
            }
            fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                fieldList.add(fields[i]);
                System.out.println("fields:" +fields[i]);
                Class fieldType = fields[i].getType();
                //判断是否为基本类型
                if(fieldType.isPrimitive() || fieldType.toString().equals("class java.lang.String")){
                    continue;
                }else{

                //是用户想要的类型?
                //if(fieldType.isAssignableFrom(List.class)){
                    Type type = fields[i].getGenericType();
                    if(type == null){
                        continue;
                    }
                    if(type instanceof ParameterizedType){//如果是泛型参数的类型
                        ParameterizedType pt = (ParameterizedType) type;
                        Class genericClass = (Class)pt.getActualTypeArguments()[0];//得到泛型的class对象
                        //System.out.println("genericClass:"+genericClass);
                        //递归直到获得所有属性
                        findFiledsAttr(genericClass);
                    }
                //}
                }
            }
            clazz = clazz.getSuperclass();
        }

        return fieldList;
    }


    public static void main(String[] args) {
        List<Field> fields= findFiledsAttr(TestGsonUnSer.class);
        for (int i = 0; i < fields.size(); i++) {
            System.out.println(fields.get(i));
        }

    }

    /**
     * 转换操作
     * @param obj  基本对象
     * @param obj2  对象中的对象
     * @param ignores  是否摒弃
     * @return
     */
    public static Map convertBean2Map(Object obj,String[] ignores){
        Map map = new LinkedHashMap();
        Class clazz = obj.getClass();
        List<Field> fields = findFiledsAttr(clazz);
        Field field = null;
        List taskList = null;
        for (int i = 0; i < fields.size(); i++) {
            field = fields.get(i);
            boolean flag = false;
            if(ignores != null && ignores.length > 0){
                flag = isExistOfIgnores(field.getName(), ignores);
            }
            if(!flag){
                Object value = getProperty(obj, field.getName());
                if(null != value/* && !StringUtils.EMPTY.equals(value.toString())*/){
                    //判断是否为基本类型
                    if(field.getType().isPrimitive() || field.getType().toString().equals("class java.lang.String")){
                        //基本类型直接设值即可
                        map.put(field.getName(), getProperty(obj, field.getName()));
                    }else if(field.getType().isAssignableFrom(List.class)){
                         PropertyDescriptor pd = getPropertyDescriptor(obj.getClass(), field.getName());
                         Method getMethod = pd.getReadMethod();
                         Object objValue = null;
                        try {
                             objValue = getMethod.invoke(obj, new Object[]{});
                            System.out.println("finalValue:"+objValue);
                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                         if(objValue instanceof List<?>){
                             System.out.println("===========================");
                             taskList = (List)objValue;
                         }

                         System.out.println("pd.getReadMethod():"+pd.getReadMethod());
                        /*//获取class类型中的propertyName属性
                        PropertyDescriptor pd = getPropertyDescriptor(obj.getClass(), field.getName());
                        //从属性描述器中获取get方法
                        Method getMethod = pd.getReadMethod();
                        System.out.println("field.getClass():"+getMethod);*/
                        //遍历嵌套对象中的元素
                        //System.out.println("obj2:"+obj2);
                        ParameterizedType pt = (ParameterizedType) field.getGenericType();
                        Class genericClass = (Class)pt.getActualTypeArguments()[0];//得到泛型的class对象
                        /*if (obj2 instanceof List<?>){
                            taskList = (List)obj2;
                        }*/
                        List<LinkedHashMap<String, Object>> sonMap = new ArrayList<LinkedHashMap<String, Object>>();
                        for (int j = 0; j < taskList.size(); j++) {
                            List<Field> sonFields = findFiledsAttr(taskList.get(j).getClass());
                            LinkedHashMap<String,Object> son2Map = new LinkedHashMap<String, Object>();
                            for (int k = 0; k < sonFields.size(); k++) {
                                System.out.println("sonFields.get(k).getName():"+sonFields.get(k).getName());
                                if(sonFields.get(k).getType().isPrimitive() || sonFields.get(k).getType().toString().equals("class java.lang.String")){
                                    son2Map.put(sonFields.get(k).getName(), getProperty(taskList.get(j), sonFields.get(k).getName()));
                                    System.out.println("子对象中的数据:"+son2Map);
                                }else{
                                    //递归至基本类型或String
                                    convertBean2Map(getProperty(taskList.get(j), sonFields.get(k).getName()));
                                }
                            }
                            sonMap.add(son2Map);
                            map.put(field.getName(), sonMap);
                        }

                    }else{
                        PropertyDescriptor pd = getPropertyDescriptor(obj.getClass(), field.getName());
                         Method getMethod = pd.getReadMethod();
                         Object objValue2 = null;
                        try {
                            objValue2 = getMethod.invoke(obj, new Object[]{});
                            System.out.println("finalValue:"+objValue2);
                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                            e.printStackTrace();
                        }
                        List<Field> sonFields = findFiledsAttr(objValue2.getClass());
                        Map<String,Object> sonMap = new LinkedHashMap<String, Object>();
                        for (int j = 0; j < sonFields.size(); j++) {
                            if(sonFields.get(j).getType().isPrimitive() || sonFields.get(j).getType().toString().equals("class java.lang.String")){
                                System.out.println("sonFields.get(j).getName():"+sonFields.get(j).getName());
                                sonMap.put(sonFields.get(j).getName(), getProperty(objValue2, sonFields.get(j).getName()));
                                System.out.println("子对象中的数据:"+sonMap);
                            }else{
                                //递归至基本类型或String
                                convertBean2Map(getProperty(objValue2, sonFields.get(j).getName()));
                            }

                        }
                        map.put(field.getName(), sonMap);
                    }
                }
            }
        }
        return map;
    }

    /**
     * 重载
     * @param obj
     * @param obj2
     * @return
     */
    public static Map convertBean2Map(Object obj){
        return convertBean2Map(obj,null);
    }

    public static Map convertBean2MapForIngoreserialVersionUID(Object obj) {
        return convertBean2Map(obj, new String[] { "serialVersionUID" });
    }


    private static boolean isExistOfIgnores(String fieldName,String[] ignores){
        boolean flag = false;
        for(String str : ignores){
            if(str.equals(fieldName)){
                flag = true;
                break;
            }
        }
        return flag;
    }


    /**
     * 通过set方法设值
     * @param obj
     * @param propertyName
     * @param value
     */
    @SuppressWarnings("unchecked")
    private static void setProperty(Object obj, String propertyName,Object value) {
        Class clazz = obj.getClass();// 获取对象的类型
        PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName);// 获取 clazz类型中的propertyName的属性描述器

        Method setMethod = pd.getWriteMethod();// 从属性描述器中获取 set 方法
        try {
            setMethod.invoke(obj, new Object[] {value});// 调用 set 方法将传入的value值保存属性中去
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 通过get方法获取对象属性值对应的值
     * @param obj
     * @param propertyName
     * @return
     */
    private static Object getProperty(Object obj,String propertyName){
        Class clazz = obj.getClass();
        //获取class类型中的propertyName属性
        PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName);
        //从属性描述器中获取get方法
        Method getMethod = pd.getReadMethod();
        Object value = null;
        try {
            //调用value方法将传入的value值保存至属性中
            value = getMethod.invoke(obj, new Object[]{});
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return value;
    }

    /**
     * get和set方法取值
     * @param clazz
     * @param propertyName
     * @return
     */
    private static PropertyDescriptor getPropertyDescriptor(Class clazz,String propertyName){
        StringBuffer sb = new StringBuffer();//存储方法名称
        Method setMethod = null;
        Method getMethod = null;
        PropertyDescriptor pd = null;
        try {
            //根据字段名获取字段
            Field f = clazz.getDeclaredField(propertyName);
            if(f != null){
                String methodEnd = propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
                //构建set方法
                sb.append("set" + methodEnd);
                setMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{f.getType()});

                //构建get方法
                sb.delete(0, sb.length());//清空
                sb.append("get"+methodEnd);
                getMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{});
                System.out.println("getMethod:"+getMethod);
                pd = new PropertyDescriptor(propertyName, getMethod,setMethod);
            }
        } catch (NoSuchFieldException e) {
            System.out.println("实体对象中没有此属性==="+e.getMessage());
        } catch (SecurityException e) {
            System.out.println("此方法为私有的或访问权限不足==="+e.getMessage());
        } catch (NoSuchMethodException e) {
            System.out.println("实体对象中的属性必须有get/set方法==="+e.getMessage());
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
        return pd;
    }

}

可以看到 , 在此工具类中通过反射机制拿到所有的属性和属性类型 , 将基本数据类型+String和对象类型分开做不同操作 , 通过方法反射拼接get和set方法取值/设值
这里重中之重依旧是分析 json 应该转换为何种类型

public static void main(String[] args) {
        String str = "[{\"users\":[{\"name\":\"系统001\",\"code\":\"sys01\"},{\"name\":\"系统003\",\"code\":\"sys03\"}],\"travel_theme\":\"测试002\",\"travel_start_time\":\"2017-08-08 10:07\",\"travel_end_time\":\"2017-08-22 10:07\",\"process_start_time\":\"2017-08-07 10:09:06\",\"process_end_time\":\"2017-08-07 10:28:46\"},{\"users\":[{\"name\":\"系统002\",\"code\":\"sys002\"}],\"travel_theme\":\"测试004\",\"travel_start_time\":\"2017-08-07 10:11\",\"travel_end_time\":\"2017-08-08 10:11\",\"process_start_time\":\"2017-08-07 10:12:34\",\"process_end_time\":\"2017-08-07 10:28:51\"}]";

        Gson gson = new Gson();
        List<TestGsonUnSer> list = gson.fromJson(str, new TypeToken<List<TestGsonUnSer>>(){}.getType());
        System.out.println("list:"+list);
        System.out.println(list.get(0).getUsers().get(0).getName());

        List<Map<String, List<Map<String, Object>>>> maps = new ArrayList<>();
        LinkedHashMap<String,List<Map<String, Object>>> sonMap = new LinkedHashMap<>();
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j <  list.get(i).getUsers().size(); j++) {
                sonMap =   (LinkedHashMap<String, List<Map<String, Object>>>) 
                //第一个参数为最外层 javaBean 类类型,第二个为 List,传入参数的同时将数据全部带入
                TestJsonUtil.convertBean2Map(list.get(i), list.get(i).getUsers());
                System.out.println("list.get(i).getUsers().get(0):"+list.get(i).getUsers().get(j));
                System.out.println("sonMap:"+sonMap);
                //maps.add(sonMap);
            }
            maps.add(sonMap);
        }
        System.out.println("maps:"+maps);
    }

最后 maps 输出

maps:[{users=[{name=系统001, code=sys01}, {name=系统003, code=sys03}], travel_theme=测试002, travel_start_time=2017-08-08 10:07, travel_end_time=2017-08-22 10:07, process_start_time=2017-08-07 10:09:06, process_end_time=2017-08-07 10:28:46}, {users=[{name=系统002, code=sys002}], travel_theme=测试004, travel_start_time=2017-08-07 10:11, travel_end_time=2017-08-08 10:11, process_start_time=2017-08-07 10:12:34, process_end_time=2017-08-07 10:28:51}]

和我们想要的结果一致

展开阅读全文

没有更多推荐了,返回首页