使用GSON和泛型解析约定格式的JSON串(转)

原文地址为: 使用GSON和泛型解析约定格式的JSON串(转)

时间紧张,先记一笔,后续优化与完善。

解决的问题:

      使用GSON泛型解析约定格式的JSON串。

背景介绍:

       1.使用GSON来进行JSON串与java代码的互相转换。

       2.JSON的格式如下三种:

         

写道
#第一种:
{
"success":true,"data":{"averageStarLevel":4.7,"remarkCount":10}}
#第二种:
{
"success":true,"data":{"page":10,"pageCount":29,"list":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}],"statistics":{"star5":20,"star4":40,"star3":30,"star2":10,"star1":0}}}
#第三种:{
"success":true,"data":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}]}

分析:

     在工作时间中,遇到一种场景,就是在应用中调用多个JSON接口,各接口返回的数据内容不一样,如果逐一解析代码会比较臃肿。JSON串如上所列有三种基本格式。经过分析,发现三种JSON串有一个共同的特点。JSON结构一致:

写道
{"success":true,"data":##} 

success:代表是否访问成功

    data:后面跟着所需信息.

   

    基本相同的JSON结构,所以想定义一种通用模型对应到此结构。但是,data中的数据类型不一致。如第一种是简单对象,第二种是对象中嵌套数组,第三种是List。针对data数据类型不一致的情况,使用泛型来解决。

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import com.google.gson.Gson;

public class CommonJson<T> implements Serializable {

/**
*
*/
private static final long serialVersionUID = -3440061414071692254L;

/**
* 是否成功
*/
private Boolean success;

/**
* 数据
*/
private T data;

public Boolean getSuccess() {
return success;
}

public void setSuccess(Boolean success) {
this.success = success;
}

public T getData() {
return data;
}

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

 GSON对于泛型的支持不足,为了使GSON对于泛型进行解析,JSON解析与组装代码如下:

       public static CommonJson fromJson(String json, Class clazz) {
Gson gson
= new Gson();
Type objectType
= type(CommonJson.class, clazz);
return gson.fromJson(json, objectType);
}

public String toJson(Class<T> clazz) {
Gson gson
= new Gson();
Type objectType
= type(CommonJson.class, clazz);
return gson.toJson(this, objectType);
}

static ParameterizedType type(final Class raw, final Type... args) {
return new ParameterizedType() {
public Type getRawType() {
return raw;
}

public Type[] getActualTypeArguments() {
return args;
}

public Type getOwnerType() {
return null;
}
};
}

 以上两段代码可以满足第一种和第二种JSON的解析,对于第三种,data是List类型的,无法得到List<>的class,所以,针对第三种格式,实现代码如下:

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

import com.google.gson.Gson;

public class CommonJson4List<T> implements Serializable {

/**
*
*/
private static final long serialVersionUID = -369558847578246550L;

/**
* 是否成功
*/
private Boolean success;

/**
* 数据
*/
private List<T> data;

public Boolean getSuccess() {
return success;
}

public void setSuccess(Boolean success) {
this.success = success;
}

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

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

public static CommonJson4List fromJson(String json, Class clazz) {
Gson gson
= new Gson();
Type objectType
= type(CommonJson4List.class, clazz);
return gson.fromJson(json, objectType);
}

public String toJson(Class<T> clazz) {
Gson gson
= new Gson();
Type objectType
= type(CommonJson4List.class, clazz);
return gson.toJson(this, objectType);
}

static ParameterizedType type(final Class raw, final Type... args) {
return new ParameterizedType() {
public Type getRawType() {
return raw;
}

public Type[] getActualTypeArguments() {
return args;
}

public Type getOwnerType() {
return null;
}
};
}

}

测试代码如下:

import java.util.ArrayList;
import java.util.List;

import com.alibaba.asc.sharewood.common.http.CommonJson;
import com.alibaba.asc.sharewood.common.http.CommonJson4List;
import com.alibaba.asc.sharewood.external.service.model.AverageStarLevelAndCount;
import com.alibaba.asc.sharewood.external.service.model.Evalution;
import com.alibaba.asc.sharewood.external.service.model.EvalutionProfile;
import com.alibaba.asc.sharewood.external.service.model.StarLevelStatistics;

public class Test {

@SuppressWarnings(
"unchecked")
public static void main(String[] args) {

CommonJson
<AverageStarLevelAndCount> cj = new CommonJson<AverageStarLevelAndCount>();
AverageStarLevelAndCount data
= new AverageStarLevelAndCount();
data.setAverageStarLevel(
4.7f);
data.setRemarkCount(
10);

cj.setSuccess(Boolean.TRUE);
cj.setData(data);

String res1
= cj.toJson(AverageStarLevelAndCount.class);

System.out.println(res1);

CommonJson
<AverageStarLevelAndCount> cj2 = CommonJson.fromJson(res1,
AverageStarLevelAndCount.
class);

System.out.println(cj2.getSuccess());
System.out.println(cj2.getData().getAverageStarLevel());

EvalutionProfile p
= new EvalutionProfile();
p.setPage(
10);
p.setPageCount(
29);

StarLevelStatistics s
= new StarLevelStatistics();
s.setStar1(
0);
s.setStar2(
10);
s.setStar3(
30);
s.setStar4(
40);
s.setStar5(
20);

p.setStatistics(s);

Evalution e1
= new Evalution();

e1.setStarLevel(
4);
e1.setRemarkTime(
"2013-02-27 07:21:48");
e1.setRemarkCotnent(
"评价方未及时做出评价,系统默认满意!");
e1.setTpLogoURL(
"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png");
e1.setExplainContent(
"");
e1.setPostMemberId(
"y**f");

Evalution e2
= new Evalution();

e2.setStarLevel(
4);
e2.setRemarkTime(
"2013-02-27 07:21:48");
e2.setRemarkCotnent(
"评价方未及时做出评价,系统默认满意!");
e2.setTpLogoURL(
"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png");
e2.setExplainContent(
"");
e2.setPostMemberId(
"y**f");

List
<Evalution> le = new ArrayList<Evalution>();
le.add(e1);
le.add(e2);

p.setList(le);

CommonJson
<EvalutionProfile> ce = new CommonJson<EvalutionProfile>();

ce.setSuccess(Boolean.TRUE);
ce.setData(p);

String res2
= ce.toJson(EvalutionProfile.class);

System.out.println(res2);

String ps
= "{\"data\":{\"pageCount\":29,\"page\":\"1\",\"list\":[{\"starLevel\":4,\"remarkTime\":\"2013-04-10 05:17:42\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"b**6\"},{\"starLevel\":4,\"remarkTime\":\"2013-04-05 04:42:40\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"b**8\"},{\"starLevel\":4,\"remarkTime\":\"2013-03-20 00:52:18\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"b**5\"},{\"starLevel\":4,\"remarkTime\":\"2013-03-07 01:51:01\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"b**7\"},{\"starLevel\":4,\"remarkTime\":\"2013-03-06 03:38:57\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"z**2\"},{\"starLevel\":4,\"remarkTime\":\"2013-03-06 03:17:33\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"b**2\"},{\"starLevel\":4,\"remarkTime\":\"2013-03-03 01:40:17\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"a**6\"},{\"starLevel\":4,\"remarkTime\":\"2013-03-01 02:41:31\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"b**4\"},{\"starLevel\":4,\"remarkTime\":\"2013-02-28 03:20:45\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\",\"tpLogoURL\":\"\",\"explainContent\":\"\",\"postMemberId\":\"t**y\"},{\"starLevel\":4,\"remarkTime\":\"2013-02-27 07:21:48\",\"explainTime\":\"\",\"remarkContent\":\"评价方未及时做出评价,系统默认满意!\","
+ "\"tpLogoURL\":\""
+ "http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png\",\"explainContent\":\"\",\"postMemberId\":\"y**f\"}],"
+ "\"statistics\":{\"star5\":59,\"star4\":38,\"star3\":2,\"star2\":1,\"star1\":0}},\"success\":true}";

CommonJson
<EvalutionProfile> re = CommonJson.fromJson(ps,
EvalutionProfile.
class);

System.out.println(re.getData().getStatistics().getStar5());

System.out.println(re.getData().getPageCount());

System.out.println(re.getData().getList().get(
0).getPostMemberId());

CommonJson4List
<Evalution> cjl = new CommonJson4List<Evalution>();

cjl.setSuccess(Boolean.TRUE);
cjl.setData(le);

System.out.println(
"###" + cjl.toJson(Evalution.class));

String sList
= "{\"data\":[{\"starLevel\":4,\"remarkCotnent\":\"评价方未及时做出评价,系统默认满意!\",\"remarkTime\":\"2013-02-27 07:21:48\",\"explainContent\":\"\",\"postMemberId\":\"y**f\",\"tpLogoURL\":\"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png\"},{\"starLevel\":4,\"remarkCotnent\":\"评价方未及时做出评价,系统默认满意!\",\"remarkTime\":\"2013-02-27 07:21:48\",\"explainContent\":\"\",\"postMemberId\":\"y**f\",\"tpLogoURL\":\"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png\"}],\"success\":true}";

CommonJson4List
<Evalution> cjle = CommonJson4List.fromJson(sList,
Evalution.
class);

System.out.println(
"***"
+ cjle.getData().get(0).getPostMemberId());

}
}

执行结果如下:

{"success":true,"data":{"averageStarLevel":4.7,"remarkCount":10}}
true
4.7
{
"success":true,"data":{"page":10,"pageCount":29,"list":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}],"statistics":{"star5":20,"star4":40,"star3":30,"star2":10,"star1":0}}}
59
29
b
**6
{
"success":true,"data":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}]}
y
**f

Ps:文中说到Gson对泛型的支持不足,其实是不正确的,Gson对泛型做了以下支持:

public static CommonJson4List fromJson(String json, Class clazz) {  
Gson gson
= new Gson();
Type objectType
= new TypeToken<CommonJson4List<clazz>>() {}.getType();
return gson.fromJson(json, objectType);
}

只需将获取类型的泛型类作为TypeToken的泛型参数构造一个匿名的子类,就可以通过getType方法获取一个parameterized类型,结果与type方法一致。


转载请注明本文地址: 使用GSON和泛型解析约定格式的JSON串(转)

猜你喜欢

转载自blog.csdn.net/xfxf996/article/details/81365101