基于原生JSON封裝解析與生成工具

將JavaBean 封裝成JSON格式的字符串

封裝JSON數(shù)據(jù)的代碼片段

     List<UserBean> listUser = new ArrayList<>(); //創(chuàng)建一個List集合
    
     Map<String, UserBean> mapUser = new HashMap<>(); //創(chuàng)建一個Map集合
    
     mapUser.put("map-key", new UserBean(4, "map-1", 10, 2.456789, null,null, null)); //添加一個map的元素
    
     listUser.add(new UserBean(3, "list-1", 17, 1.456, null, null, null));//添加一個list的元素
    
     UserBean[] arrayUser = { new UserBean(2, "array-1", 16, 10.0123456,null, null, null) }; //創(chuàng)建一個對象數(shù)組并添加一個元素
    
     UserBean us = new UserBean(1, "大白", 18, 3.230, listUser, mapUser,arrayUser); //將list map 對象數(shù)組 都設置到JavaBean當中
    
     Pson pson = Pson.Instance(); //初始化工具類
     /**
      * 使用工具進行封裝JavaBean中的所有字段
      */
     String jsonStr = pson.objectToJson(us);
     System.out.println(jsonStr);
     /**
      * 使用工具進行封裝JavaBean中的ID 與名字
      */
     jsonStr = pson.objectToJson(us,"id","name");
     System.out.println(jsonStr);

封裝JSON格式后的數(shù)據(jù)

//封裝所有的字段
{"id":1,"name":"大白","age":18,"money":3.23,"listUser":[{"id":3,"name":"list-1","age":17,"money":1.456}],"mapUser":{"map-key":{"id":4,"name":"map-1","age":10,"money":2.456789}},"arrayUser":[{"id":2,"name":"array-1","age":16,"money":10.0123456}]}

//封裝指定的字段
{"id":1,"name":"大白"}    

將JSON格式字符串解析成Object實體類

首先準備兩個JSON格式的數(shù)據(jù) 一個為對象 一個為數(shù)組

JSON-1: String jsonStr = {"id":1,"name":"大白","age":18,"money":1.0453}

JSON-2: String jsonArray = [{"id":1,"name":"大白","age":18,"money":2.0453},{"id":1,"name":"大白","age":18,"money":1.0453}]

解析對象

    Pson pson = Pson.Instance();
    /**
     * 調用工具類進行解析 一參為被解析的類的class對象 二參為JSON格式的字符串數(shù)據(jù)
     */
    UserBean ub = pson.jsonToObject(UserBean.class, jsonStr);
    System.out.println(ub);
    
    //解析完畢后打印的ub對象
    UserBean [id=1, name=大白, age=18, money=1.0453, listUser=null, mapUser=null, arrayUser=null]

解析數(shù)組

    UserBean users[] = {}; // 首先先初始化一個空的數(shù)組
    users = pson.jsonToObject(users.getClass(), jsonArray);
    for (UserBean u : users) {
        System.out.println(u);
    }
    
    //解析完畢后打印的數(shù)組元素
    UserBean [id=1, name=大白1, age=18, money=1.0453, listUser=null, mapUser=null, arrayUser=null]
    UserBean [id=2, name=大白2, age=18, money=2.0453, listUser=null, mapUser=null, arrayUser=null]

JSON工具類

使用工具類前需要有原生org.json包 <a href="http://www.reibang.com/p/35ed550c5c9a">前往下載</a>

之前因為不太喜歡第三方的東西 雖然知道有Gson這類的第三方工具

所以自己動手寫了一個工具

public class Pson {
    private String pattern = "yyyy-MM-dd HH:mm:ss";//時間格式

    public void setPattern(String pattern) {
        this.pattern = pattern;
    }

    public static final Pson pson = new Pson();

    public static Pson Instance() {
        return pson;
    }

    private Pson() {
        
    }

    /**
     * 將對象 轉換成JSON格式的字符串
     *
     * @param object    需要封裝的對象
     * @param fieldName 需要封裝的指定字段 如果為空 則封裝所有字段
     * @return 返回封裝后的JSON格式的字符串
     */
    public Object objectToJson(Object object, String... fieldName) {
        return ObjectToString(object, fieldName);
    }

    /**
     * 將對象 轉換成JSON格式的字符串
     *
     * @param object
     * @param fieldName 需要封裝指定的字段
     * @return 接收到之后 調用toString即可
     */
    private Object ObjectToString(Object object, String... fieldName) {
        if (object == null) {
            return null;
        } else if (object instanceof List<?>) { // 判斷是否是List集合
            List<Object> list = (List<Object>) object;
            JSONArray array = new JSONArray();
            if (list.size() != 0) {
                Object oneObject = list.get(0);// 先取出第一個元素 然后判斷是否是基本數(shù)據(jù)類型
                // 或者String類型
                if (toBasicData(oneObject)) { // 元素是基本數(shù)據(jù)類型
                    for (Object element : list) {
                        array.put(element);
                    }
                } else {
                    for (Object element : list) {
                        array.put(ObjectToString(element, fieldName));
                    }
                }
            }
            return array;
        } else if (object.getClass().isArray()) {
            Object oArray[] = (Object[]) object;
            JSONArray jsonArray = new JSONArray();
            /**
             * 判斷數(shù)組長度
             */
            if (oArray.length != 0) {
                if (toBasicData(oArray[0])) { // 判斷數(shù)組的元素是基本數(shù)據(jù) 還是對象
                    for (Object elementObject : oArray) {
                        jsonArray.put(elementObject);
                    }
                } else {
                    for (Object elementObject : oArray) {
                        jsonArray.put(ObjectToString(elementObject, fieldName));
                    }
                }
            }
            return jsonArray;
        } else if (object instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) object;
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            JSONObject jsonObject = new JSONObject();
            if (fieldName.length != 0) {//判斷是否需要解析指定的字段
                for (String keyName :
                        fieldName) {
                    jsonPutMap(jsonObject, keyName, map.get(keyName), fieldName);
                }
            } else {
                /**
                 * 遍歷MAP集合
                 */
                for (Map.Entry<String, Object> entry : entries) {
                    jsonPutMap(jsonObject, entry.getKey(), entry.getValue(), fieldName);
                }
            }
            return jsonObject;
        } else if (object instanceof Date) { //時間類
            return new SimpleDateFormat(pattern).format((Date) object);
        }
        JSONObject json = new JSONObject();
        Class<?> c = object.getClass();
        Field fs[] = null;
        if (fieldName != null && fieldName.length != 0) { // 判斷是否需要 取出指定的字段
            int len = fieldName.length;
            fs = new Field[len];
            int i = 0;
            for (String s : fieldName) {
                try {
                    fs[i] = c.getDeclaredField(s);
                } catch (NoSuchFieldException | SecurityException e) {
                    e.printStackTrace();
                }
                i++;
            }
        } else {
            fs = c.getDeclaredFields();
        }

        for (Field f : fs) {
            if (f == null)
                continue;
            f.setAccessible(true);
            try {
                Object o = f.get(object);
                if (o != null) { // 判斷屬性內容是否為空
                    if (toBasicData(o)) { // 判斷是否是基本數(shù)據(jù)類型 或者是String類型
                        json.put(f.getName(), o);
                    } else { // 可能是一個JavaBean 或者是集合
                        json.put(f.getName(), ObjectToString(o, fieldName));
                    }
                } else {
                    json.put(f.getName(), o);
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return json;
    }

    /**
     * 判斷是否是字符串 或者是 基本數(shù)據(jù)類型
     *
     * @param object
     * @return 基本數(shù)據(jù)類型|字符串類型 返回true
     */
    private boolean toBasicData(Object object) {
        if (object == null) {
            return false;
        } else if (object instanceof String || object instanceof Integer || object instanceof Boolean
                || object instanceof Character || object instanceof Byte || object instanceof Short
                || object instanceof Long || object instanceof Float || object instanceof Double) {
            return true;
        }
        return false;
    }

    /**
     * 判斷是否是字符串 或者是 基本數(shù)據(jù)類型
     *
     * @param oc
     * @return 基本數(shù)據(jù)類型|字符串類型 返回true
     */
    private boolean toBasicData(Class<?> oc) {
        if (oc.isPrimitive() || oc.isAssignableFrom(String.class) || oc.isAssignableFrom(Integer.class)
                || oc.isAssignableFrom(Boolean.class) || oc.isAssignableFrom(Character.class)
                || oc.isAssignableFrom(Byte.class) || oc.isAssignableFrom(Short.class)
                || oc.isAssignableFrom(Long.class) || oc.isAssignableFrom(Float.class)
                || oc.isAssignableFrom(Double.class)) {
            return true;
        }
        return false;
    }

    /**
     * 將JSON轉JavaBean對象實例
     *
     * @param oClass  JavaBean的Class對象
     * @param jsonStr JSON對象
     * @param <T>
     * @return
     */
    public <T> T jsonToObject(Class<?> oClass, String jsonStr) {
        T objectData = null;
        try {
            if (oClass.isArray()) {// 該class為數(shù)組的時候
                JSONArray array = new JSONArray(jsonStr);
                int len = array.length();
                // 獲取到數(shù)組元素的class
                Class<?> ComponentType = oClass.getComponentType();
                Object createArray = Array.newInstance(ComponentType, array.length());// 創(chuàng)建一個與JSON數(shù)組長度相同的數(shù)組
                if (toBasicData(ComponentType.newInstance())) { // 進行判斷是否是基本數(shù)據(jù)類型或字符串類型
                    for (int i = 0; i < len; i++) {
                        Array.set(createArray, i, array.get(i));
                    }
                } else {
                    for (int i = 0; i < len; i++) {
                        Array.set(createArray, i, jsonToObject(ComponentType, array.get(i).toString()));
                    }
                }
                objectData = (T) createArray;
            } else if (oClass.isAssignableFrom(Date.class)) {//時間類型
                Date parse = new SimpleDateFormat(pattern).parse(jsonStr);
                objectData = (T) parse;
            } else {// 如果不是數(shù)組的話 則默認以JavaBean的形式進行解析
                objectData = (T) oClass.newInstance(); // 創(chuàng)建該class的對象的實例
                JSONObject json = new JSONObject(jsonStr);
                Field[] fields = oClass.getDeclaredFields();// 獲取到所有的屬性
                for (Field fs : fields) {// 開始遍歷屬性
                    fs.setAccessible(true);
                    Class<?> cl = fs.getType(); // 取出該屬性代表的class
                    String fieldName = fs.getName(); // 取出該屬性的名稱
                    /**
                     * 判斷該屬性名字在json中不為空
                     */
                    if (!json.isNull(fieldName)) {
                        String jsonData = json.get(fieldName).toString();

                        /**
                         * 判斷 屬性字段是否是數(shù)組類型
                         */
                        if (cl.isArray()) {
                            fs.set(objectData, analyticArray(cl, jsonData));
                        } else if (toBasicData(cl)) { // 基本數(shù)據(jù)類型
                            fs.set(objectData, json.get(fieldName));
                        } else if (cl.isInterface()) { // 接口
                            Object oj = analyticInterface(cl, (ParameterizedType) fs.getGenericType(), jsonData);
                            fs.set(objectData, oj);
                        } else if (cl.isAssignableFrom(ArrayList.class)) { // 判斷該成員屬性是否為ArrayList集合
                            Object oj = analyticInterface(List.class, (ParameterizedType) fs.getGenericType(),
                                    jsonData);
                            fs.set(objectData, oj);
                        } else if (cl.isAssignableFrom(HashMap.class)) { // 判斷該成員屬性是否為HashMap集合
                            Object oj = analyticInterface(Map.class, (ParameterizedType) fs.getGenericType(), jsonData);
                            fs.set(objectData, oj);
                        } else { // 如果以上條件都沒有成立 則當對象來解析
                            fs.set(objectData, jsonToObject(cl, jsonData));
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objectData;
    }

    /**
     * 解析數(shù)組數(shù)據(jù)
     *
     * @param arrayClass 數(shù)組的class對象
     * @param jsonStr    Json格式的字符串數(shù)據(jù)
     * @return
     */
    private Object analyticArray(Class<?> arrayClass, String jsonStr) {
        try {
            // 首先 先獲取到數(shù)組的子元素的類型class
            Class<?> componentType = arrayClass.getComponentType();
            // 判斷子元素類型 是否是基本類型 或者是String類型
            boolean is = toBasicData(componentType.newInstance());
            JSONArray jsonArray = new JSONArray(jsonStr);
            int len = jsonArray.length();
            /**
             * 創(chuàng)建一個與該數(shù)組類型一至 長度與JSONArray長度一致的數(shù)組
             */
            Object elementObject = Array.newInstance(componentType, len);
            if (is) {
                for (int i = 0; i < len; i++) {
                    Array.set(elementObject, i, jsonArray.get(i));
                }
            } else { // 如果不是基本數(shù)據(jù)類型的話 則調用解析對象的方法
                for (int i = 0; i < len; i++) {
                    Array.set(elementObject, i, jsonToObject(componentType, jsonArray.getString(i)));
                }
            }
            return elementObject;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 解析成員屬性為接口的方法 只支持Map List 集合接口 其他的 均返回null
     *
     * @param interfaceClass    接口Class對象
     * @param jsonStr           JSON格式的文本
     * @param parameterizedType 泛型的管理
     * @return 返回解析后的實例
     */
    private Object analyticInterface(Class<?> interfaceClass, ParameterizedType parameterizedType, String jsonStr) {
        Object breakObject = null;
        try {
            if (interfaceClass.isAssignableFrom(List.class)) { // List集合
                JSONArray array = new JSONArray(jsonStr);
                int len = array.length();
                Class<?> c = (Class<?>) parameterizedType.getActualTypeArguments()[0];// 獲取到List集合的泛型
                List<Object> list = new ArrayList<>();
                if (toBasicData(c)) {// 判斷List的泛型是否為String 或基本類型
                    for (int i = 0; i < len; i++) {
                        list.add(array.get(i));
                    }
                } else {// 調用解析對象方法
                    for (int i = 0; i < len; i++) {
                        list.add(jsonToObject(c, array.getString(i)));
                    }
                }
                breakObject = list;
            } else if (interfaceClass.isAssignableFrom(Map.class)) {
                /**
                 * 如果是map集合的話 是會有兩個泛型的 對應的為 key value
                 */
                Class<?> k = (Class<?>) parameterizedType.getActualTypeArguments()[0];
                Class<?> v = (Class<?>) parameterizedType.getActualTypeArguments()[1];
                if (!k.isAssignableFrom(String.class)) {
                    throw new ClassCastException("key 請用String類型");
                } else {
                    Map<String, Object> map = new HashMap<>();
                    JSONObject json = new JSONObject(jsonStr);
                    Iterator<String> iterator = json.keys();
                    if (toBasicData(v)) {// 判斷value是否為基本類型或String類型
                        while (iterator.hasNext()) {
                            String key = iterator.next();
                            map.put(key, json.get(key));
                        }
                    } else {
                        while (iterator.hasNext()) {
                            String key = iterator.next();
                            map.put(key, jsonToObject(v, json.getString(key)));
                        }
                    }
                    breakObject = map;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return breakObject;
    }

    /**
     * JSON put map的key values
     *
     * @param jsonObject
     * @param key
     * @param values
     * @param fieldName
     */
    private void jsonPutMap(JSONObject jsonObject, String key, Object values, String... fieldName) {
        try {
            if (toBasicData(values)) {// 判斷是否是基本數(shù)據(jù)類型
                jsonObject.put(key, values);
            } else {
                jsonObject.put(key, ObjectToString(values, fieldName));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末莲祸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌澈侠,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡怔匣,警方通過查閱死者的電腦和手機击胜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門亏狰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人偶摔,你說我怎么就攤上這事暇唾。” “怎么了辰斋?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵策州,是天一觀的道長。 經常有香客問我宫仗,道長够挂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任藕夫,我火速辦了婚禮孽糖,結果婚禮上,老公的妹妹穿的比我還像新娘毅贮。我一直安慰自己办悟,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布滩褥。 她就那樣靜靜地躺著病蛉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瑰煎。 梳的紋絲不亂的頭發(fā)上铺然,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音丢间,去河邊找鬼探熔。 笑死,一個胖子當著我的面吹牛烘挫,可吹牛的內容都是我干的诀艰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饮六,長吁一口氣:“原來是場噩夢啊……” “哼其垄!你這毒婦竟也來了?” 一聲冷哼從身側響起卤橄,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤绿满,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后窟扑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喇颁,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡漏健,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了橘霎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔫浆。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖姐叁,靈堂內的尸體忽然破棺而出瓦盛,到底是詐尸還是另有隱情,我是刑警寧澤外潜,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布原环,位于F島的核電站,受9級特大地震影響处窥,放射性物質發(fā)生泄漏嘱吗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一碧库、第九天 我趴在偏房一處隱蔽的房頂上張望柜与。 院中可真熱鬧,春花似錦嵌灰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至剩瓶,卻和暖如春驹溃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背延曙。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工豌鹤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人枝缔。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓布疙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親愿卸。 傳聞我的和親對象是個殘疾皇子灵临,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容