Gson提供了fromJson()
和toJson()
两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化。
今天在使用 fromJson()
遇到一个无法识别泛型的问题。
我的需求是通过fromJson()
反序列化返回一个List。
主要代码如下:
1 2 3 4 5 6 7 8
| public List<T> select(T var) { List<T> list = Lists.newArrayList(); ... ... JsonArray jsonArray = jsonObject.getAsJsonObject("d").getAsJsonArray("results"); list = gson.fromJson(jsonArray, new TypeToken<ArrayList<T>>() {}.getType()); return list; }
|
T 的当前类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Getter @Setter public class AvsPerson {
@SerializedName(value = "Person") private String person;
@SerializedName(value = "PersonWorkAgreement") private String personWorkAgreement;
@SerializedName(value = "PersonFullName") private String personFullName; }
|
jsonArray的数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| { "__metadata": { "id": "1", "uri": "2", "type": "3" }, "Person": "9980000020", "PersonWorkAgreement": "50000000", "PersonFullName": "Sarah Huang" }, { "__metadata": { "id": "1", "uri": "2", "type": "3" }, "Person": "9980000021", "PersonWorkAgreement": "50000002", "PersonFullName": "Shanna Sun" }
|
反序列化后List中的值:
数据是已经到list中了,但是它不是我需要的那个AvsPerson
类型,而是完全把jsonArray
中的数据反序列化为一个Map。
DEBUG跟一下发现如下:
直接把T
当成一个Type
了。。
因此我怀疑Gson没有识别到我使用的泛型类,所以直接当成 Object
类型了,我测试把 T
换成Object
是一样的结果,Type
中则显示为Object
类型了。
经过一番摸索,解决方案如下:
使用 Guava
,它也是Google
家的,直接引入依赖即可:
1 2 3 4 5 6
| <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0.1-jre</version> </dependency>
|
使用如下方法:
1 2 3 4 5
| public <T> Type setModelAndGetCorrespondingList(Class<T> type) { return new TypeToken<ArrayList<T>>() {} .where(new TypeParameter<T>() {}, type) .getType(); }
|
这里的 TypeToken
使用的是 Guava
下的包了,注意更换。
在代码中调用这个方法即可:
1 2 3 4 5 6 7 8
| public List<T> select(T var) { List<T> list = Lists.newArrayList(); ... ... JsonArray jsonArray = jsonObject.getAsJsonObject("d").getAsJsonArray("results"); list = gson.fromJson(jsonArray, classHelper.setModelAndGetCorrespondingList(var.getClass())); return list; }
|
更改后再次 debug 后 Type
的类型正常了!
得到的List内容也恢复正常:
具体的原因可以看这里:https://stackoverflow.com/questions/20773850/gson-typetoken-with-dynamic-arraylist-item-type