【本文范围】:

本文并非JSON知识讲解资料,亦非GSON知识讲解资料,而是通过实例让开发人员了解通过Gson如何使Java对象和Json对象进行相互转换。

【JSON参考资料】:

Json快速入门:http://www.w3school.com.cn/json/index.asp

Json官网:http://www.json.org/

【GSON参考资料】:

Gson官网:http://code.google.com/p/google-gson/

一、JSON基础知识:

1、Json概念:

Json全称JavaScript object notation(Javascript对象表示法),是轻量级的文本数据交换格式,它独立于语言和平台,用来描述数据对象,具有自我描述性、容易理解等特性。

2、举例:

{“TeamName":"hr", "NewProject":true, "Leader":"wang", "Employee":[{"name":"li", "BelongTo":"train"}, {"name":"kpi", "BelongTo":"Security"}, {"name":"liu", "BelonTo":"service"}]}

这个Json对象描述了hr项目组。项目组名称为hr,是一个新项目,Leader是wang,有三个员工,分别为负责培训的li,负责Security的kpi和负责服务的liu。

3、Json语法

数据以健值对形式描述(如:"TeamName":"hr");

数据以逗号分隔;

花括号保存对象(如{"Name":"li", "BelongTo":"train"});

方括号保存数组(如"csn":[20,21,22,23]);

4、Json值:

数字(整数或浮点数);

字符串(在双引号中);

逻辑值(true或false);

数组(在方括号中);

对象(在花括号中);

null

二、实例演习:

实例1:在查询告警窗口中对告警流水号为2012的记录做“清除”操作

【思路】:

假如清除操作的命令码为41,那么向服务端请求的JSON对象应该为{“cmdCode”:41, “csn”:2012}

【演示代码】:

1、定义AlarmClearCondition.java

public class AlarmClearCondition
{
private int cmdCode = 0;
private int csn = 0;
public void setCmdCode(int cmdCode)
{
thisNaNdCode = cmdCode;
}
public void setCsn(int csn)
{
this.csn= csn;
}
}

2、使用Gson把AlarmClearCondition对象转换为Json对象

AlarmClearConditioncondition = new AlarmClearCondition();
condition.setCmdCode(41);
condition.setCsn(2012);
Gson gson = newGson();
String jsonCond= gson.toJson(condition);

实例2:在查询告警窗口中对告警流水号为2012和2013的记录做“清除”操作

【思路】:

与实例1不同,这里的CSN有两个,意味着告警流水号CSN必须是一个数组,那么向服务端请求的JSON对象应该为{“cmdCode”:41, “csn”:[2012, 2013]}

【演示代码】:

1、改造AlarmClearCondition.java定义,使csn变成一个集合csnList

public class AlarmClearCondition
{
private int cmdCode = 0;
private List<Integer> csnList = newArrayList<Integer>();
public void setCmdCode(int cmdCode)
{
thisNaNdCode = cmdCode;
}
public void setCsn(int csn)
{
csnList.add(csn);
}
}

2、把AlarmClearCondition对象转换为Json对象

AlarmClearConditioncondition = new AlarmClearCondition();
condition.setCmdCode(41);
condition.setCsn(2012);
condition.setCsn(2013);
Gson gson = newGson();
String jsonCond= gson.toJson(condition);

实例3:若实例2中对流水号2012和2013的两条记录“清除”成功后,服务端返回的结果为{“errorCode”:0, “errorMsg”:“Clear alarmssuccessful!”, “clearedCsn”:[2012, 2013]},则客户端如何把这个结果解析为Java对象?

【思路】:

1、直接用硬编码进行解析未尝不可,但代码不够优雅。

2、与生成Json对象一样定义一个Java类,剩余的转换工作由Gson协助完成。见演示代码。

【演示代码】:

1、定义AlarmClearResult类

public class AlarmClearResult
{
private int errorCode = 0;
privateString errorMsg = null;
private List<Integer> clearedCsn = new ArrayList<Integer>(); public int getErrorCode()
{
return errorCode;
} public String getErrorMsg()
{
return errorMsg;
} public List<Integer> getClearedCsn()
{
return clearedCsn;
}
}

2、把Json对象转换为AlarmClearResult对象

AlarmClearResult result =gson.fromJson(jsonObject, AlarmClearResult.class);

实例4:当前屏最后一条告警记录流水号为44531611,查询下一屏告警记录时与服务端约定请求条件为{“FieldName”:”logId”,”Operator”:”<”, “value”:44531611},使用Gson把Java对象转换为此Json对象,但要求Java的属性字段定义为是“驼峰”风格。

【思路】:

1、不考虑属性字段定义“驼峰”风格问题,那只需要把FileName、Operator和value作为Java类的属性即可,见演示代码1。

2、为使Java属性字段定义和显示为不同的值,Gson提供了@SerializedName注释,见演示代码2.

【演示代码1】:

1、定义EndlessQuery类

public class EndlessQuery
{
private String FieldName = null;
private String Operator = null;
private int value = 0; public void setFieldName(String filedName)
{
this.FieldName = fieldName;
} public void setOperator(String operator)
{
this.Operator = operator;
} public void setValue(int value)
{
this.value = value;
}
}

2、把AlarmClearResult转换为JSON对象

EndlessQueryqueryCond = new EndlessQuery();
queryCond.setFiledName(“logId”);
queryCond.setOperator(“<”);
queryCond.setValue(44531611);
Gson gson = newGson();
System.out.println(gson.toJson(queryCond));

【演示代码2】:

只修改EndlessQuery类的FileName和Operator两个字段即可,其余保持不变,如下:

public class EndlessQuery
{
@SerializedName(“FieldName”)
private String fieldName= null;
@SerializedName(“Operator”)
private String operator= null;
private int value = 0; public void setFieldName(String filedName)
{
this.fieldName = fieldName;
} public void setOperator(String operator)
{
this.operator = operator;
}
public void setValue(int value)
{
this.value = value;
}
}

实例5:列举一个稍微真实的场景,告警监控TOPN是指客户端向任意一个应用服务下发请求后,应用服务从各个数据服务中读取最新上报的TOPN条告警记录,然后再把获取的告警记录按条件进行重排序取TOPN条给客户端。

假如监控TOPN的命令码为22,每次监控40条最新的告警记录,在获取这40条最新的告警记录时使用的排序条件为“按网元发生时间”和“告警流水号”进行降序排序,其JSON对象为{"CmdCode":22, "Limit":40, "VersionID":0, "SortCond":[{"FieldName":"occurNeTime", "SortOrder":"desc","Priority":1},{"FieldName":"logId", "SortOrder":"desc", "Priority":6}]},则客户端如何生成这个JSON对象?

【思路】:

1、直接拼凑字符串代码(不是本文的意图)。

2、定义属性字段为CmdCode、Limit、VersionID和SortCond的类,但SortCond与其它字段不同之处在于SortCond是一个集合,这个集合中对象类型必须能够描述出按“网元发生时间”和“流水号”进行排序。

【演示代码】:

1、定义排序SortConditionBean对象

public class SortConditionBean
{
@SerializedName("FieldName")
private String fieldName = null;
@SerializedName("SortOrder")
private String order = null;
@SerializedName("Priority")
private int priority = 0; public void setFieldName(String fieldName)
{
this.fieldName = fieldName;
}
public void setOrder(String order)
{
this.order = order;
}
public void setPriority(int priority)
{
this.priority = priority;
}
}

2、定义监控TOPN对象MonitorTopnCond类

public class MonitorTopnCond
{
@SerializedName("CmdCode")
private int cmdCode = 0;
@SerializedName("VersionID")
private int versionID = 0;
@SerializedName("Limit")
private int limit = 0;
@SerializedName("SortCond")
private List<SortCondtionBean> sortCond = new ArrayList<SortConditionBean>(): public void setCmdCode(int cmdCode)
{
this.cmdCode = cmdCode;
}
public void setVersionID(int versionID)
{
this.versionID = versionID;
}
public void setLimit(int limit)
{
this.limit = limit;
}
public void setSortCond(SortConditionBean sortItem)
{
this.sortCond.add(sortItem);
}
}

3、测试方法:

SortConditionBean occuTime = new SortConditionBean();
occuTime.setFieldName("occurNeTime");
occuTime.setOrder("desc");
occuTime.setPriority(1); SortConditionBean logID = new SortConditionBean();
logID.setFieldName("logId");
logID.setOrder("desc");
logID.setPriority(6); MonitorTopnCond topnCond = new MonitorTopnCond();
topnCond.setCmdCode(22);
topnCond.setLimit(40);
topnCond.setVersionID(0);
topnCond.setSortCond(occuTime);
topnCond.setSortCond(logID); Gson gson = new Gson();
System.out.println(gson.toJson(topnCond));

实例6:实例5中向应用服务下发监控TopN请求之后,应用服务从各个数据分区读取数据后,再重排序取了Top40条告警记录返回客户端,结果如下(为简单起见这里把40条告警记录改成1条):

{
"ErrorMsg": "0",
"LastVersionId": 0,
"ResultCode":0,
"TotalNum":24006,
"records":
[
{
"Basic":["链路断连","BTS","NE=10009","NE=10009","Location=Test1, m_strPara=1","",-1,19],
"Paras":[0,0,0,0,0,19,0,0,0,0],
"intExt":[[0,0,0,0,0,0,0,0,0,0],[134, 13528,0,0,4,199,199]],
"strExt":[["","",""], ["","","","","127.0.0,1","",""]]
}
]
}

客户端如何解析这个Json对象呢?

【思路】:

仔细观察返回结果可发现,它由ErrorMsg、LastVersionId、ResultCode、TotalNum、records构成,所以可以定义一个Java类使其包含这五个属性字段。重要的一点records不同于ErrorMsg等属性字段,它又由有Basic、Paras、intExt和strExt构成。

【演示代码】:

1、定义告警记录对象AlarmRecord,对应record集合中的一个元素。

public class AlarmRecord
{
@SerializedName("Basic")
private List<Object> basicField = null;
@SerializedName("Paras")
private List<Integer> parasField = null;
@SerializedName("intExt")
private int[][] intExtField = null;
@SerializedName("strExt")
private String[][] strExtField = null; public List<Object> getBasicField()
{
return basicField;
} public List<Integer> getParasField()
{
return parasField;
} public int[][] getIntExtField()
{
return intExtField;
} public String[][] getStrExtField()
{
return strExtField;
}
}

2、定义结果响应对象AlarmResponseRecord

public class AlarmResponseRecord
{
@SerializedName("ResultCode")
private int errorCode = 0;
@SerializedName("ErrorMsg")
private String errorMessage = null;
@SerializedName("LastVersionId")
private int versionID = 0;
@SerializedName("TotalNum")
private int totalNum = 0;
private List<ALarmRecord> records = null; public int getErrorCode()
{
return errorCode;
}
public String getErrorMessage()
{
return errorMessage;
} public int getVersionID()
{
return versionID;
} public int getTotalNum()
{
return totalNum;
} public List<AlarmRecord> getRecords()
{
return records;
}
}

3、测试方法:

String result = "{'ErrorMsg':'ccq', 'LastVersionId':0, 'ResultCode':0, 'TotalNum':24006, 'records':[{'Basic':[0,'通讯系统',3,0,0,0,'链路断连'], 'Paras':[0,0,0,19,0,0], 'intExt':[[1,2,3,4,5],[6,7,8,9,11]], 'strExt':[['a','b','c','d'],['','','']]}]}";
Gson gson = new Gson();
AlarmResponseRecord almRecords = gson.fromJson(result, AlarmResponseRecord .class);
System.out.println(almRecords.getRecords());

实例7:告警监控TOPN请求的JSON对象为:

{"CmdCode":22,"Limit":40,"VersionID":0,"SortCond":[{"FieldName":"occurNeTime", "SortOrder":"desc", "Priority":1},{"FieldName":"logId", "SortOrder":"desc","Priority":6}]}

告警无尽列表查询请求的JSON对象为

{"CmdCode":21,"Limit":41,"SortCond":[{"FieldName":"occurNeTime", "SortOrder":"desc", "Priority":1},{"FieldName":"logId", "SortOrder":"desc","Priority":6}],"EndlessTableCond":[{"FieldName":"occurNeTime", "Operator":"=","value":[1355899366]},{"FieldName":"logId", "Operator":"<","value":[33394632]}]}

仔细观察会发现这两个请求的JSON对象结构非常类似,如何使用一个Java对象生成这两个Json对象呢?

【思路】:

很容易想到的是把相同的数据作为Java的属性字段(如CmdCode、Limit、SortCond),不同的数据作为子类属性字段(如EndlessTableCond、VersionID),使用Java的继承机制可实现。

【演示代码】:

1、定义排序对象SortConditionBean

public class SortConditionBean
{
@SerializedName("FieldName")
private String fieldName = null;
@SerializedName("SortOrder")
private String order = null;
@SerializedName("Priority")
private int priority = 0; public void setFieldName(String fieldName)
{
this.fieldName = fieldName;
}
public void setOrder(String order)
{
this.order = order;
}
public void setPriority(int priority)
{
this.priority = priority;
}
}

2、定义无尽列表查询对象EndlessConditionBean

public class EndlessConditionBean
{
private String FieldName = null;
private String Operator = null;
private int value = 0;
public void setFieldName(String fieldName)
{
this.FieldName = fieldName;
}
public void setOperator(String operator)
{
this.Operator = operator;
}
public void setValue(int value)
{
this.value = value;
}
}

3、定义公共父类AlarmConditionBean对象

public class AlarmConditionBean
{
@SerializedName("CmdCode")
private int cmdCode = 0;
@SerializedName("Limit")
private int limit = 0;
@SerializedName("SortCond")
private List<SortConditionBean> sortCond = new ArrayList<SortConditionBean>(); public void setCmdCode(int cmdCode)
{
thisNaNdCode = cmdCode;
}
public void setLimit(int limit)
{
this.limit = limit;
}
public void setSortCond(SortConditionBean sortItem)
{
this.sortCond.add(sortItem);
}
}

5、定义监控AlarmMonitorBean类

public class AlarmMonitorBean extends AlarmConditionBean
{
@SerializedName("VersionID")
private int versionID = 0;
public void setVersionID(int versionID)
{
this.versionID = versionID;
}
}

6、定义查询AlarmQueryBean类

public class AlarmQueryBean extends AlarmConditionBean
{
@SerializedName("EndlessTableCond")
private List<EndlessConditionBean> queryCond = new ArrayList<EndlessConditionBean>();
public void setEndlessCond(EndlessConditionBean endlessItem)
{
queryCond.add(endlessItem);
}
}

7、测试代码

测试告警监控TOPN

SortConditionBean occuTimeSortItem = new SortConditionBean();
occuTimeSortItem.setFieldName("occurNeTime");
occuTimeSortItem.setOrder("desc");
occuTimeSortItem.setPriority(1); SortConditionBean logIDSortItem = new SortConditionBean();
logIDSortItem.setFieldName("logId");
logIDSortItem.setOrder("desc");
logIDSortItem.setPriority(6); AlarmMonitorBean monitorCond = new AlarmMonitorBean();
monitorCond.setCmdCode(22);
monitorCond.setLimit(40);
monitorCond.setVersionID(0);
monitorCond.sortSortCond(occuTimeSortItem);
monitorCond.sortSortCond(logIDSortItem); Gson gson = new Gson();
System.out.println(gson.toJson(monitorCond));

测试告警无尽列表查询:

SortConditionBean occuTimeSortItem = new SortConditionBean();
occuTimeSortItem.setFieldName("occurNeTime");
occuTimeSortItem.setOrder("desc");
occuTimeSortItem.setPriority(1); SortConditionBean logIDSortItem = new SortConditionBean();
logIDSortItem.setFieldName("logId");
logIDSortItem.setOrder("desc");
logIDSortItem.setPriority(6); EndlessConditionBean occuTimeEndlessItem = new EndlessConditionBean();
occuTimeEndlessItem.setFieldName("occurNeTime");
occuTimeEndlessItem.setOperator("=");
occuTimeEndlessItem.setValue(1355899366); EndlessConditionBean logIDEndlessItem = new EndlessConditionBean();
logIDEndlessItem.setFieldName("logId");
logIDEndlessItem.setOperator("<");
logIDEndlessItem.setValue(33394632); AlarmQueryBean queryCond = new AlarmQueryBean();
queryCond.setCmdCode(21);
queryCond.setLimit(41);
queryCond.setSortCond(occuTimeSortItem);
queryCond.setSortCond(logIDSortItem);
queryCond.setEndlessCond(occuTimeEndlessItem);
queryCond.setEndlessCond(logIDEndlessItem); Gson gson = new Gson();
System.out.println(gson.toJson(queryCond));

【备注】:

关于此例还有一种解决方式,即使用Gson的@Since注释,但这样会影响代码的易读性,不建议使用,有兴趣的读者可以了解一下Gson的API

实例8:服务端返回给客户端的数据只是一个数组,如[96301,0,1,"链路断连","BTS","NE=1009"],此时客户端如何解析?

【思路】:

JSON对象在定义数据时明确指出数据是一个键值对,但并不表明Gson不能解析,因为这也是一个Json对象,这样做的目的主要是为了减少通讯传输量给带宽带来的拥挤。假如各字段的含义如下:

96301 0 1 链路断连 BTS NE=1009
告警流水号 清除状态 确认状态 告警类型 告警源类型 告警源

【演示代码】:

1、定义告警记录AlarmRecord类

final class AlarmSimpleRecord
{
private int logID = 0;
private int clearStatus = 0;
private int confirmStatus = 0;
private String alarmType = null;
private String neType = null;
private String neFDN = null; public int getLogID()
{
return logID;
}
public void setLogID(int logID)
{
this.logID = logID;
} public int getClearStatus()
{
return clearStatus;
}
public void setClearStatus(int clearStatus)
{
this.clearStatus = clearStatus;
} public int getConfirmStatus()
{
return confirmStatus;
}
public void setConfirmStatus(int confirmStatus)
{
this.confirmStatus = confirmStatus;
} public String getAlarmType()
{
return alarmType;
}
public void setAlarmType(String alarmType)
{
this.alarmType = alarmType;
} public String getNeType()
{
return neType;
}
public void setNeType(String neType)
{
this.neType = neType;
} public String getNeFDN()
{
return neFDN;
}
public void setNeFDN(String neFDN)
{
this.neFDN = neFDN;
}
}

2、解析演示

public class AlarmRecord
{
/**
* 定义各字段的序号
*/
private static final int LOG_ID = 0;
private static final int CLEAR_STATUS = 1;
private static final int CONFIRM_STATUS = 2;
private static final int ALARM_TYPE = 3;
private static final int NE_TYPE = 4;
private static final int NE_FDN = 5; public static void main(String[] args)
{
String result = "[96031, 0 ,1, '链路断连','BTS', 'NE=10009']";
Gson gson = new Gson();
JsonElement resultElement = gson.fromJson(result, JsonElement.class);
if(resultElement.isJsonNull())
{
// do nothing.
return;
} AlarmSimpleRecord record = new AlarmSimpleRecord();
JsonArray elementArray = resultElement.getAsJsonArray();
record.setLogID(elementArray.get(LOG_ID).getAsInt());
record.setClearStatus(elementArray.get(CLEAR_STATUS).getAsInt());
record.setConfirmStatus(elementArray.get(CONFRIM_STATUS).getAsInt());
record.setAlarmType(elementArray.get(ALARM_TYPE).getAsString());
record.setNeType(elementArray.get(NE_TYPE).getAsString());
record.setNeFDN(elementArray.get(NE_FDN).getAsString()); System.out.println(record);
}
}

本文转自:http://qingkechina.blog.51cto.com/5552198/1299025

Gson ------ 实例演习的更多相关文章

  1. [转]Gson过滤字段

    原文地址:http://my.oschina.net/orgsky/blog/368768 摘要 Gson过滤字段 Gson过滤字段 Gson 过滤 字段 属性 目录[-] 最简单的用法 方法1:排除 ...

  2. GSON使用笔记(1) -- 序列化时排除字段的几种方式

    http://blog.csdn.net/zxhoo/article/details/21471005 GSON是Google发布的JSON序列化/反序列化工具,非常容易使用.本文简要讨论在使用GSO ...

  3. 解决Android开发中,ActiveAndroid和Gson同时使用,对象序列化失败的问题

    ActiveAndroid是安卓开发常用的ORM框架. Gson则是Google提供的轻量级序列化框架,非常适合Android开发使用. 但这两者同时使用,会产生序列化失败的问题.你通常会收到如下信息 ...

  4. Okhttp、Volley和Gson的简单介绍和配合使用

    转载自:http://www.apkbus.com/home.php?mod=space&uid=784586&do=blog&id=61255 1.okhttp是一个高效的. ...

  5. Java 中 Gson的使用

    JSON 是一种文本形式的数据交换格式,它比XML更轻量.比二进制容易阅读和编写,调式也更加方便;解析和生成的方式很多,Java中最常用的类库有:JSON-Java.Gson.Jackson.Fast ...

  6. Gson的入门使用

    Java对象和Json之间的互转,一般用的比较多的两个类库是Jackson和Gson,下面记录一下Gson的学习使用. 基础概念:  Serialization:序列化,使Java对象到Json字符串 ...

  7. 你真的会用Gson吗?Gson使用指南(2)

    注:此系列基于Gson 2.4. 上一篇文章 你真的会用Gson吗?Gson使用指南(1) 我们了解了Gson的基础用法,这次我们继续深入了解Gson的使用方法. 本次的主要内容: Gson的流式反序 ...

  8. 完全理解Gson(1):简单入门

    GSON是Google开发的Java API,用于转换Java对象和Json对象.本文讨论并提供了使用API的简单代码示例.更多关于GSON的API可以访问:http://sites.google.c ...

  9. 完全理解Gson(2):Gson序列化

    通过调用 Gson API 可以把 Java 对象转换为 JSON 格式的字符串(项目主页).在这篇文章中,我们将会讲到如何通过 Gson 默认实现和自定义实现方式,将 Java  对象转换为 JSO ...

随机推荐

  1. EasyUI中combotree允许多选的时候onSelect事件会重复触发onCheck事件

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgEAAADkCAIAAACOkmAuAAAgAElEQVR4nO2dW2wc15nnO0EQBJsdzA

  2. json(gson) 转换html标签带来的麻烦

    gson 转换html标题时,会把html(特殊字符转换为unicode编码) ,所以为了避免这个问题GsonBuilder类 有一个 disablehtmlEscaping方法. 就可以让gson类 ...

  3. ios tableview 上加 textfiled

    ios tableview 上加 textfiled 首先附上我项目中用曾经用到的几张图  并说明一下我的用法: 图1: 图2: 图3: 心在你我说一下  我当初的实现 方法 ,希望能给你们一些  启 ...

  4. 基于C#的IBM消息队列操作客户端

    背景: 做XX项目需要把交易的消息推送给YY系统,技术选型MQ 另:选用MQ原因是为了防止YY系统宕机,无法接受收消息 实现 1.安装IBM WebSphere MQ客户端 2.引用amqmdnet. ...

  5. java新手笔记5 类

    1.进制转换 /* 企业发放的奖金根据利润提成. 利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时, 低于10万元的部分按10%提成,高于10万元的部分,可提成7.5 ...

  6. html表单 第四节

    实例: <html> <head> <title>表单实例</title> </head> <body> <center& ...

  7. 享元模式(咖啡屋)【java与模式】

    package com.javapatterns.flyweight.coffeeshop; public class Flavor extends Order { private String fl ...

  8. 04_过滤器Filter_03_多个Filter的执行顺序

    [Filter链] *在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为一个Filter链. *web服务器根据Filter在web.xml中的注册顺序,决定先调用哪个Fi ...

  9. STUN/TURN/ICE协议在P2P SIP中的应用(一)

    1           说明 本文详细描述了基于STUN系列协议实现的P2P SIP电话过程,其中涉及到了SIP信令的交互,P2P的原理,以及STUN.TURN.ICE的协议交互 本文所提到的各个服务 ...

  10. (转)Libevent(5)— 连接监听器

    转自:http://name5566.com/4220.html 参考文献列表:http://www.wangafu.net/~nickm/libevent-book/ 此文编写的时候,使用到的 Li ...