getData({
"data": {
"_112727": {
"id": "112727",
"num": "周六093",
"date": "2018-10-28",
"time": "10:00:00",
"b_date": "2018-10-27",
"status": "Selling",
"hot": "0",
"l_id": "102",
"l_cn": "墨西哥超级联赛",
"h_id": "1645",
"h_cn": "蓝十字",
"a_id": "861",
"a_cn": "墨西哥美洲",
"index_show": "0",
"show": "1",
"hhad": {
"a": "4.75",
"d": "3.60",
"h": "1.56",
"goalline": "",
"p_code": "HHAD",
"o_type": "F",
"p_id": "505424",
"p_status": "Selling",
"single": "0",
"allup": "0",
"fixedodds": "+1",
"cbt": "2",
"int": "2",
"vbt": "2",
"h_trend": "0",
"a_trend": "0",
"d_trend": "0",
"l_trend": "0"
},
"had": {
"a": "2.14",
"d": "2.95",
"h": "3.10",
"goalline": "",
"p_code": "HAD",
"o_type": "F",
"p_id": "505423",
"p_status": "Selling",
"single": "0",
"allup": "0",
"fixedodds": "",
"cbt": "2",
"int": "2",
"vbt": "2",
"h_trend": "0",
"a_trend": "0",
"d_trend": "0",
"l_trend": "0"
},
"l_cn_abbr": "墨超",
"h_cn_abbr": "蓝十字",
"a_cn_abbr": "墨美洲",
"h_order": "[墨超3]",
"a_order": "[墨超2]",
"h_id_dc": "1461",
"a_id_dc": "1458",
"l_background_color": "339900",
"weather": "大致多云",
"weather_city": "",
"temperature": "13°",
"weather_pic": "http:\/\/static.sporttery.cn\/www\/images\/weather_logo\/cloudy.png",
"match_info": []
}
})
这是一个非严谨的json格式字符串,我需要从中取出data里面的每一条信息,最后存入数据库中,这个时候,我采用了string对字符串进行截取,让他成为一个完整的json格式的字符串
//截取所获得的字符串
String str = EntityUtils.toString(entity);
//因为字符串太长,超过了int的范围,所以不能用.length来确定他的长度并截取。
str = str.substring(str.indexOf("(") + 1, str.indexOf(")"));
得到截取之后的字符串,即为一个完整的json格式的字符串,我这里采用的是json-lib对字符串进行一个解析,以下为解析的步骤。
1.Json-lib 需要的 jar 包
2.对数据结构进行分析,并采用合适的方法对其进行解析
我们使用json工具包对json格式数据进行解析,常用的主要是有两种,一种是转换集合,一种是转换对象,两种方式都有各自适用的具体情况以及一些不适用之处,但是他们也有相互转化之处,相对来说,我更喜欢使用JSONObject,因为在我看来集合也是对象。
//将字符串转换为json对象
JSONObject jsonObject = JSONObject.fromObject(str);
//获得有用的json数据
JSONObject jsonOb = jsonObject.getJSONObject("data");
//获取该对象的所有的key
Iterator it = jsonOb.keys();
//这里使用迭代器完成对所有key的遍历,一一获取每一个对象
while (it.hasNext()) {
// 遍历所有的key
String key = it.next();
//将数据存到想对应的类中,比赛
JSONObject ob = jsonOb.getJSONObject(key);
Integer id = ob.getInt("id");
String num = ob.getString("num");
String date = ob.getString("date");
String time = ob.getString("time");
String l_cn_abbr = ob.getString("l_cn_abbr");
String h_cn_abbr = ob.getString("h_cn_abbr");
String a_cn_abbr = ob.getString("a_cn_abbr");
//将数据存到相对应的类中
BiSai bisai = new BiSai(id, num, date, time, l_cn_abbr, h_cn_abbr, a_cn_abbr);
//上半场的胜平负数据
JSONObject hhad = ob.getJSONObject("hhad");
String a = hhad.getString("a");
String d = hhad.getString("d");
String h = hhad.getString("h");
String fixedodds = hhad.getString("fixedodds");
//将获得的数据存到类中,信息
XinXi xinxi = new XinXi(id, a, d, h, fixedodds);
//下半场的胜平负数据
JSONObject had = ob.getJSONObject("had");
if (!had.isNullObject()) {
a = had.getString("a");
d = had.getString("d");
h = had.getString("h");
fixedodds = had.getString("fixedodds");
//将获得的数据存到类中,信息
XinXi xinxi2 = new XinXi(id, a, d, h, fixedodds);
//调用service将数据存进去
jingCaiService.setJingCai(bisai, xinxi, xinxi2);
}
}
我这里首先将他解析为json对象,然后获取其中对我有用的json对象,这个时候,我之前有想过将它转化为Array,但是后来放弃了,因为如果转化为array,那么Array中的每一个元素都将是以一种hashmap的形式存在,当然,这个时候map它的每一个键都是在不断变化的(每次抓取都是自动抓取数据),而且不能够很好的去解析,所以我将它转化为JsonObject,之后获取它里面所有的键,之后利用迭代器对它进行一个遍历,得到每一个与想要的实体类相对应的数据。之后对其进行封装即可!
3.遇到的问题及解决方案
在数据封装的过程中,一直报一个错误,“null object”,之前有在网上找过各个大牛的一些总结,都不得其法,之后对这个数据进行分析,发现,在报错的地方,是少了对象,因为这个数据是爬取出来的,而人家网站的数据是上传到数据库然后展示到页面上的,但是,人家上传的过程中可能因为各种原因,某条数据不存在,也就是对象的子对象不存在,这个时候就报了这么一个错误。没有这个对象!
找到原因之后,我尝试用各种非空判断方法,但都没有效果,最后发现这个异常时json-lib的异常,也就是它的对象的异常,(自定义异常类)之后就看了jsonObject的源码,找到了这个异常发生的地方,发现它有一个public的非空判断机制,这个时候拿来用就可以完美的解决问题了 。
以下是JSONObject中的关于这个异常产生的一些个方法。
//私有化成员变量
private boolean nullObject;
//来自jsonObject的问候,定义非空判断
public boolean isNullObject() {
return this.nullObject;
}
//发现问题抛出异常
private void verifyIsNull() {
if (this.isNullObject()) {
throw new JSONException("null object");
}
}
算是对一个复杂的json字符串进行了解析。遇到问题解决问题,积极思考,妖怪终究是和打不过葫芦娃的。