通過GSON解析複雜json數據(二)

這裏我們依舊用上文中的 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}]

和我們想要的結果一致

發佈了141 篇原創文章 · 獲贊 851 · 訪問量 185萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章