您的位置:首页 > Web前端 > JavaScript

使用Gson解析泛型类型

2016-05-21 22:56 513 查看
在程序中访问网络的时候返回的Json有时候是固定的形式,我们所需要的json信息是以嵌套的形式给出的,比如

User info:

{
"result_code":"4000",
"result_msg":"接受数据正常",
"json_msg":{
"user_name":"jack",
"user_age":15
}
}


Book info:

{
"result_code":"4000",
"result_msg":"接受数据正常",
"json_msg":{
"book_name":"Java编程思想",
"book_price":"108.00"
}
}


如果我们直接用Gson解析的话,要有对应的实体类才行,比如要解析上面的两个Json的话,就要有两个类

public class UsreInfoBean {
public String result_code;
public String result_msg;
public UserInfo json_msg;
}

public class BookInfoBean {
public String result_code;
public String result_msg;
public BookInfo json_msg;
}


另外还需要UserInfo和BookInfo两个类:

public class UserInfo {
public String user_name;
public int user_age;
}

public class BookInfo{
public String book_name;
public String book_price;
}


这样的话每个Json都要对应两个类,很繁琐,另外如果Json比较多的话,会产生很多类,而这些类有一半都是多余的,维护起来也很麻烦。

观察UserInfoBean和BookInfoBean两个类,可以发现这两个类中的成员变量除了json_msg字段的类型不一样,其他的都完全一样,如果能把这连个类统一成一个类的话就能解决类多余的问题。Java的泛型恰好可以解决这个问题。上面的连个类用泛型可以写为:

public class InfoBean<T> {
public String result_code;
public String result_msg;
public T json_msg;
}


此时,UserInfoBean和BookInfoBean两个类就可以写成InfoBean和InfoBean,不管有多上类都可以写成这种形式。

试着我们常用的Gson用法去去解析json,

String json = ...; //对应上面的User info的json
//下面代码在android studio中会报错
InfoBean<UserInfo> userInfo = new Gson().fromJson(json, InfoBean<UserInfo>.class);


上面的代码并不能运行,原因是InfoBean是泛型,并不能直接获取class类型。通过android studio的代码提示功能可以看到Gson的fromJson()方法解析String类型的json有两种:

Object fromJson(Sting, Class<Object>)
Object fromJson(String, Type)


第一个方法就是我们一般常用的,接受class类型, 第二个方法接受一个Type类型,Type类型一般与与泛型的类型推断有关,查阅这个方法的文档可以发现这个方法就是用来处理泛型类型的,文档中介绍需要用TypeToken来获取泛型的type类型,并且给出了具体的用法:

Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();


按照上面的形式现在我们来处理InfoBean:

String json = ...; //对应上面的User info的json
Type type = new TypeToken<InfoBean<UserInfo>>(){}.getType();
InfoBean<UserInfo> userInfo = new Gson.fromJson(json, type);


现在就可以正确的获取userInfo对象了。

另外,一般情况下,在json对应的实体类中,类的成员变量的名字要和json对应字段的名字一样才能正确解析,比如上面的User info的json中的”result_code”字段在InfoBean类中要有result_code成员变量来对应。而我们在开发安卓程序的时候一般习惯用驼峰命名法,即result_code字段一般习惯用resultCode来命名。

Gson对这种情况也是有处理的,只要使用一个注解就可以解决问题:


@SerializedName("result_code")


注解中的名字对应json中的字段名字,这时我们就可以对实体类中的成员变量随便命名了。对InfoBean加上注解后:

public class InfoBean<T> {
@SerializedName("result_code")
public String resultCode;

@SerializedName("result_msg")
public String resultMsg;

@SerializedName("json_msg")
public T resultObj;
}


这样我们在代码中访问json实体类的时候,代码的阅读性就会提高很多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  json-嵌套 泛型 gson