json轉實體,json轉List實體,json轉泛型實體


1、=========================

https://segmentfault.com/a/1190000009523164

package com.thunisoft.maybee.engine.utils;

import com.google.gson.Gson;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * Json2Bean / Json2List / Json2List<T>
 *
 * @author hcq
 */
public class GsonUtil {

    private GsonUtil() {

    }

    /**
     * Json 轉為 bean
     *
     * @param json
     * @param type
     * @param <T>
     * @return
     */
    public static <T> T bean4Json(String json, Class<T> type) {
        Gson gson = new Gson();
        return gson.fromJson(json, type);

    }

    /**
     * Json 轉為 List<bean>
     *
     * @param json
     * @param typeclazz
     * @param <T>
     * @return
     */
    public static <T> List<T> list4Json(String json, Class<T> typeclazz) {
        ParameterizedTypeImpl type = new ParameterizedTypeImpl(typeclazz);
        Gson gson = new Gson();
        return gson.fromJson(json, type);
    }

    /**
     * 參數類型轉換
     */
    private static class ParameterizedTypeImpl implements ParameterizedType {
        private Class clazz;

        public ParameterizedTypeImpl(Class clz) {
            clazz = clz;
        }

        public Type[] getActualTypeArguments() {
            return new Type[]{clazz};
        }

        public Type getRawType() {
            return List.class;
        }

        public Type getOwnerType() {
            return null;
        }
    }

    public static void main(String[] args) {

        String json1 = "{\"id\":1,\"name\":\"eric\"}";
        String json2 = "[{\"id\":1,\"name\":\"eric\"},{\"id\":2,\"name\":\"john\"}]";
        String json3 = "{\"page\":1,\"size\":10,\"total\":2,\"data\":[{\"id\":1,\"name\":\"eric\"},{\"id\":2,\"name\":\"john\"}]}";

        String helloworld = "helloworld!";
        String bl = "false";
        String integer = "123";
        String db = "23423d";

        User user = GsonUtil.bean4Json(json1, User.class);
        List<User> lists = GsonUtil.list4Json(json2, User.class);
        Page<User> page = GsonUtil.bean4Json(json3, Page.class);

        String res1 = GsonUtil.bean4Json(helloworld, String.class);
        Boolean res2 = GsonUtil.bean4Json(bl, Boolean.class);
        Integer res3 = GsonUtil.bean4Json(integer, Integer.class);
        Double res4 = GsonUtil.bean4Json(db, Double.class);

        System.out.println("user:" + user);
        System.out.println("lists:" + lists);
        System.out.println("page:" + page);

        User user1 = lists.get(0);
        System.out.println("user1:" + user1);

        System.out.println("===");

        System.out.println(res1);
        System.out.println(res2);
        System.out.println(res3);
        System.out.println(res4);
    }

    private class Page<T> {
        private int page;

        private int size;

        private int total;

        private List<T> data;

        public int getPage() {
            return page;
        }

        public void setPage(int page) {
            this.page = page;
        }

        public int getSize() {
            return size;
        }

        public void setSize(int size) {
            this.size = size;
        }

        public int getTotal() {
            return total;
        }

        public void setTotal(int total) {
            this.total = total;
        }

        public List<T> getData() {
            return data;
        }

        public void setData(List<T> data) {
            this.data = data;
        }

        @Override
        public String toString() {
            return "User [page=" + page + ", size=" + size + ", total=" + total + ", data=" + data + "]";
        }
    }

    private class User {
        private int id;

        private String name;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + "]";
        }
    }
}

  

2/=========================

https://www.jianshu.com/p/701ae370f959

通常情況下,Server端返回的json數據應該可以一次性完全解析,但是要是遇到server返回的json里又包含json字符串就得自己再手動解析一次了。

我們知道json字符串解析成模型類型很簡單,但是如果要把json數組字符串解析List對象,應該怎么辦呢?

舉一個實際的例子:

[
    {
        "name": "zhaoxa",
        "score": 100
    },
    {
        "name": "zhaoxa2",
        "score": 76
    },
    {
        "name": "zhaoxa3",
        "score": 99
    },
    {
        "name": "zhaoxa4",
        "score": 48
    }
]
根據這個json字符串列表,我們設計名為Student的數據模型,Parcelable接口可以使用AS插件一鍵生成:

public class Student implements Parcelable{
    String name;
    int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.score);
    }

    protected Student(Parcel in) {
        this.name = in.readString();
        this.score = in.readInt();
    }

    public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel source) {
            return new Student(source);
        }

        @Override
        public Student[] newArray(int size) {
            return new Student[size];
        }
    };
}
現在開始着手解析這個json數組字符串。

1. 先轉成數組,再轉成List
最常規的方法把jsonString轉化為T[]數組,然后再使用Arrys.asList將數組轉為List。

Student[] array = new Gson().fromJson(jsonString,Student[].class);
List<Student> list = Arrays.asList(array);
Log.i("lxc"," ---> " + list);
通過斷點,可以看到list下面的數據已經轉為Student類型了。


2. 使用TypeToken進行轉化
Type type = new TypeToken<List<Student>>(){}.getType();
List<Student> list = new Gson().fromJson(jsonString,type);

3. 如何使用泛型抽象
假設不只一個json數組字符串需要你解析,很顯然重復的代碼應該抽象成一個方法。

假設現在有關於書籍的信息,json數組內容如下:

[
    {
        "author": "zhaoxa",
        "name": "如何入門android",
        "price": 100
    },
    {
        "author": "zhaoxa2",
        "name": "如何入門android2",
        "price": 76
    },
    {
        "author": "zhaoxa3",
        "name": "如何入門android3",
        "price": 99
    },
    {
        "author": "zhaoxa4",
        "name": "如何入門android4",
        "price": 48
    }
]
同樣的,我們得新建一個Book類,難道必須得復制之前的代碼進行操作么?能不能抽象一個泛型的方法出來,把json數組字符串轉化成類。

好的,應該可以的,我們進行以下嘗試:

第一次嘗試

報錯了,fromJson不支持使用泛型解析。

第二次嘗試
public <T> List<T> parseString2List(String json) {
        Type type = new TypeToken<List<T>>(){}.getType();
        List<T> list = new Gson().fromJson(jsonString,type);
        return list;
    }
嗯,沒有報錯,我們運行時斷點看看list里的數據類型。

我們通過這句話調用方法:

List<Student> list = parseString2List(jsonString);

可以看到,list中的數據類型不是Student,而是LinkedTreeMap,LinkedTreeMap是Gson庫內部數據模型,換句話說我們的解析失敗了,嘗試着將parseString2List方法中的泛型T去掉,運行結果一樣,說明Gson解析時不支持泛型。


真的就沒有辦法了么,難道解析數組json必須得重復調用相似的代碼?嗯,在接觸ParameterizedType接口之前,你應該很難實現這個功能。但是現在知道了ParameterizedType接口,我們就有了第三次嘗試。

第三次嘗試
    public <T> List<T> parseString2List(String json,Class clazz) {
        Type type = new ParameterizedTypeImpl(clazz);
        List<T> list =  new Gson().fromJson(json, type);
        return list;
    }

    private  class ParameterizedTypeImpl implements ParameterizedType {
        Class clazz;
        
        public ParameterizedTypeImpl(Class clz) {
            clazz = clz;
        }

        @Override
        public Type[] getActualTypeArguments() {
            return new Type[]{clazz};
        }

        @Override
        public Type getRawType() {
            return List.class;
        }

        @Override
        public Type getOwnerType() {
            return null;
        }
    }
在調用的地方使用:

List<Student> list = parseString2List(jsonString, Student.class);
List<Book> list2 = parseString2List(jsonString, Book.class);
斷點查看解析結果,嗯,完美解析~



好的,現在在回過頭來看看,ParameterizedType的幾個方法的含義吧,以HashMap<String,Integer>為例。

getActualTypeArguments 返回實際類型組成的數據,即new Type[]{String.class,Integer.class}

getRawType 返回原生類型,即 HashMap

getOwnerType 返回 Type 對象,表示此類型是其成員之一的類型。例如,如果此類型為 O<T>.I<S>,則返回 O<T> 的表示形式。 如果此類型為頂層類型,則返回 null。這里就直接返回null就行了。

<div align ="right">寫於 9/7/2017 4:52:27 PM</div>

作者:orzangleli
鏈接:https://www.jianshu.com/p/701ae370f959
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM