使用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串(转)的更多相关文章
- 菜鸟学习Spring——SpringMVC注解版解析不同格式的JSON串
一.概述 不同格式的JSON串传到后台来实现功能这个是我们经常要做的一件事,本篇博客就给大家介绍四种不同的JSON串传到后台后台如何用@RequestBody解析这些不同格式的JSON串的. 二.代码 ...
- Android 解析未知格式的json数据
1.递归一有的时候我们需要解析未知的json.或者说是动态的json.那么我们并不知道key具体是多少,或者说key不是固定的.这时候就需要解析动态key的方法. 这个方法是我在实现解析前台传入的js ...
- Gson解析list类型的json串
Gson gson = new Gson(); Type type = new TypeToken<List<Object>>() {}.getType(); List< ...
- new JSONObject(str)无法解析 报错:org.json.JSONException: Value of type java.lang.String cannot be converted to JSONObject
org.json.JSONException: Value of type java.lang.String cannot be converted to JSONObject 解析服务器返回的Jso ...
- GSON转换日期数据为特定的JSON数据
通过JSON传递数据的时候经常需要传递日期,Java中可以通过GSON将日期转换为特定格式的JSON数据. 1.普通的GSON转换日期 public void query(HttpServletReq ...
- python中文json串创建与解析
下面代码,举例说明了json如何创建和解析含有中文的json串: #coding=gbk import os import sys reload(sys) sys.setdefaultencoding ...
- SpringMVC Jackson 库解析 json 串属性名大小写自动转换问题
问题描述 在项目开发中,当实体类和表中定义的某个字段为 RMBPrice,首字母是大写的,sql 查询出来的列名也是大写的 RMBPrice,但是使用 jquery 的 ajax 返回请求响应时却出错 ...
- Reflection和Expression Tree解析泛型集合快速定制特殊格式的Json
很多项目都会用到Json,而且大部分的Json都是格式固定,功能强大,转换简单等,标准的key,value集合字符串:直接JsonConvert.SerializeObject(List<T&g ...
- Gson 是google解析Json的一个开源框架,同类的框架fastJson,JackJson
Gson 是google解析Json的一个开源框架,同类的框架fastJson,JackJson等等 本人fastJson用了两年,也是从去年才开始接触Gson,希望下面的总结会对博友有用,至于Gso ...
随机推荐
- 浅谈区间DP的解题时常见思路
一.区间DP解题时常见思路 如果题目中答案满足: 大的区间的答案可以由小的区间答案组合或加减得到 大的范围可以由小的范围代表 数据范围较小 我们这时可以考虑采用区间DP来解决. 那么常见的解法有两种: ...
- 灵活、可高度自定义的——Progress进度圈、弹窗、加载进度、小菊花
DDProgressHUD的介绍 提供了四种类型的展示: 显示无限旋转的加载图(比如小菊花,可以自定义),显示文字信息.网络刷新时经常用到. 显示加载进度的动画,也可以显示文字.网络下载时用的比较多, ...
- 搭建RabbitMQ集群(通用)
RabbitMQ在Erlang node(节点)上 Erlang天生具有集群特性,非常好搭建集群,每一个节点(node)上具有一个叫erlang.Cookie的东西,也是一个标识符,可以互认. 1). ...
- 【Alsa】播放声音和录音详细流程
linux中,无论是oss还是alsa体系,录音和放音的数据流必须分析清楚.先分析alsa驱动层,然后关联到alsa库层和应用层. 二,链接分析: 1)链路一 usr/src/linux-source ...
- expect学习笔记及实例详解【转】
1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...
- (转载)mysql:“Access denied for user 'root'@'localhost'”
原文地址:http://www.linuxidc.com/Linux/2007-05/4338.htm # /etc/init.d/mysql stop# mysqld_safe --user=mys ...
- 【linux】sed -e 's/-//g'
sed是用来处理文本的 s/正则表达式/替换字符串/ :表示将正则表达式的内容替换为后面的字符串 g :表示替换全部,即如果不加g,则只会替换第一个 -e :多点编辑(这个没懂) 例 ...
- linux下实用命令
也使用了一段时间的debian,过程中总结了一些常用的又实用的命令,在这里分享给大家=.= 很多命令选项很多,在这里我只总结最实用的一些选项提供给大家,详细选项解释大家可以去问google. 1.df ...
- nGrinder的安装与使用
背景 性能压测工具之前使用的是jmeter,这次说的是nGrinder,先直接搬运两者之间的比较 比较点 JMeter nGrinder 结果 实现语言 Java Java = License Apa ...
- Android 插件化 开发
插件化知识详细分解及原理 之Binder机制https://blog.csdn.net/yulong0809/article/details/56841993 插件化知识详细分解及原理 之代理,hoo ...