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 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。
