JSON三种数据解析方法

2018年01月15日 13:05:01 zhoujiang2012 阅读数:7896
 
 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/oman001/article/details/79063278

引言

JSON数据现在是我们开发中用的最多的,百分之八十的数据都是通过JSON方式进行传输,那么想要学好JSON解析就要了解什么是JSON数据,怎么快速解析它从而提升开发效率。

  • 什么是JSON数据?

下面这里有一段JSON数据,我们根据这段数进行讲解:

{
"feeds": [
{
"id": 299080,
"oid": 288342,
"category": "article",
"data": {
"subject": "视频直播:马英九会面",
"summary": "两岸领导人、马英九在新加坡会面",
"cover": "/Attachs/Article/288342/56a263bcab4a4c55b0bef0528ce880b6_padmini.JPG",
"pic": "",
"format": "video",
"changed": "2015-11-07 14:35:22"
}
},
{
"id": 299076,
"oid": 288340,
"category": "article",
"data": {
"subject": "荔枝新闻3.0:不止是阅读",
"summary": "江苏广电旗下资讯类手机应用“荔枝新闻”于近期推出全新升级换代的3.0版。",
"cover": "/Attachs/Article/288340/3e8e2c397c70469f8845fad73aa38165_padmini.JPG",
"pic": "",
"format": "txt",
"changed": "2015-09-22 16:01:41"
}
}
],
"PageIndex": 1,
"PageSize": 20,
"TotalCount": 53521,
"TotalPage": 2677
}

其实JSON数据就是一段字符串而已,只不过有不同意义的分隔符将其分割开来而已,我们看上面的符号,里面有[] ,{}等符号,其中
1 []中括号代表的是一个数组;
2 {}大括号代表的是一个对象
3 双引号“”表示的是属性值
4 冒号:代表的是前后之间的关系,冒号前面是属性的名称,后面是属性的值,这个值可以是基本数据类型,也可以是引用数据类型。

了解了JSON数据的格式,怎么对这段数据进行解析呢?

  • JSONObject系统自带的解析方式解析

我们先来JSONObject(系统自带的类)类中的方法:

上面用红框框出来的是我们手动解析最常用的方法了吧,好了,现在我们想要解析上面的一段数据,该怎么做呢?这里我写了一个解析类如下:

public class JsonUtils {

    /**
* 根据json数据解析返回一个List<HashMap<String, Object>>集合
* @param json json数据
* @return
*/
public static List<HashMap<String, Object>> getJsonList(String json) {
List<HashMap<String, Object>> dataList;
dataList = new ArrayList<>();
try {
JSONObject rootObject = new JSONObject(json);
JSONObject paramzObject = rootObject.getJSONObject("paramz");
JSONArray feedsArray = paramzObject.getJSONArray("feeds");
for (int i = 0; i < feedsArray.length(); i++) {
JSONObject sonObject = feedsArray.getJSONObject(i);
JSONObject dataObject = sonObject.getJSONObject("data");
String subjectStr = dataObject.getString("subject");
String summaryStr = dataObject.getString("summary");
String coverStr = dataObject.getString("cover");
HashMap<String, Object> map = new HashMap<>();
map.put("subject", subjectStr);
map.put("summary", summaryStr);
map.put("cover", coverStr);
dataList.add(map);
}
return dataList;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}

相信很简单一看就懂了吧,主要是比较费时间罢了,无非就是几个方法不停的调用而已,所以显得特别的费时费力,下面我又写了一个解析的方法,方法中会有一些冗余的代码,是为了更加深刻理解JSON解析而写的,实际中可以删掉,也用了一行GSON解析,GSON解析下面会见讲到:

其中DataModel对象我是将data对象使用GsonFormat插件工具生成的,使用方式可以自行搜索

public class DataModel {

    /**
* subject : 视频直播:马英九会面
* summary : 两岸领导人、马英九在新加坡会面
* cover : /Attachs/Article/288342/56a263bcab4a4c55b0bef0528ce880b6_padmini.JPG
* pic :
* format : video
* changed : 2015-11-07 14:35:22
*/ public String subject;
public String summary;
public String cover;
public String pic;
public String format;
public String changed; @Override
public String toString() {
return "DataModel{" +
"subject='" + subject + '\'' +
", summary='" + summary + '\'' +
", cover='" + cover + '\'' +
", pic='" + pic + '\'' +
", format='" + format + '\'' +
", changed='" + changed + '\'' +
'}';
}
}
 /**
* 根据json对象获取List<DataModel>集合
* @param json 数据
* @return
*/
public static List<DataModel> getGsonList(String json) {
List<DataModel> dataList;
try {
JSONObject rootObject = new JSONObject(json);
JSONObject paramzObject = rootObject.getJSONObject("paramz"); /**
* JSONArray的构造方法获取JSONArray对象
*/
JSONArray jsonArray = new JSONArray(paramzObject.getString("feeds"));
Log.i(TAG, "jsonarray.length():"+jsonArray.length()); /**
* 获取JSONObject对象的属性关键字
*/
Iterator<String> iterators = paramzObject.keys();
while (iterators.hasNext()) {
Log.i(TAG, "iterators: " + iterators.next());
}
JSONArray feeds = paramzObject.getJSONArray("feeds");
dataList = new ArrayList<>();
for (int i = 0; i < feeds.length(); i++) {
JSONObject jsonObject = feeds.getJSONObject(i);
DataModel model = new Gson().fromJson(jsonObject.getString("data"), new TypeToken<DataModel>() {
}.getType());
Log.i(TAG, "DataModel: " + model.toString());
dataList.add(model);
}
return dataList;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return null;
}

Log信息如下:

简单总结一下上面的解析吧:
1 对于JSONObject对象来说,想要得到一个JSONObject对象通常可以通过
(a):构造方式:JSONObject(String json)-> JSONObject rootObject = new JSONObject(json);
(b):JSONObject getJSONObject(String name){}-> JSONObject paramzObject = rootObject.getJSONObject(“paramz”);

2 对于JSONArray对象来说,想要得到一个JSONArray对象通常可以通过
(a):构造方式:JSONArray(String json)->JSONArray jsonArray = new JSONArray(paramzObject.getString(“feeds”));
(b):JSONObject getJSONObject(String name){}-> JSONArray feeds = paramzObject.getJSONArray(“feeds”);

JSON数据链接如下:
http://litchiapi.jstv.com/api/GetFeeds?column=0&PageSize=20&val=100511D3BE5301280E0992C73A9DEC41&pageIndex=1


  • Gson解析

我们如果懂得了上面的手动解析方式的话,那么对于Gson解析而言,就太简单了,下面我们就开始解析下面一段JSON数据:

{
"homeadlist": [
{
"id": 1,
"imgurl": "/img/homead/a73b3f1d-0f14-429d-9d0f-70643fb0f0eb.jpg",
"jumpflag": 0,
"jumpurl": "",
"posflag": 1,
"remark": "1111",
"cityid": 1
},
{
"id": 12,
"imgurl": "/img/homead/eb442fbf-49db-4ba6-a102-d781505f426d.jpg",
"jumpflag": 0,
"jumpurl": "",
"posflag": 2,
"remark": "",
"cityid": 1
},
{
"id": 14,
"imgurl": "/img/homead/68109460-635d-4c5c-8be8-64d7c7889d18.jpg",
"jumpflag": 0,
"jumpurl": "http://shiranlife.kuaizhan.com/",
"posflag": 4,
"remark": "",
"cityid": 1
}
]
}

首先我们使用GsonFormat工具生成一个类HomeadListModel:

public class HomeadListModel {

    /**
* code : 1
* data : {"homeadlist":[{"id":1,"imgurl":"/img/homead/a73b3f1d-0f14-429d-9d0f-70643fb0f0eb.jpg","jumpflag":0,"jumpurl":"","posflag":1,"remark":"1111","cityid":1},{"id":12,"imgurl":"/img/homead/eb442fbf-49db-4ba6-a102-d781505f426d.jpg","jumpflag":0,"jumpurl":"","posflag":2,"remark":"","cityid":1},{"id":14,"imgurl":"/img/homead/68109460-635d-4c5c-8be8-64d7c7889d18.jpg","jumpflag":0,"jumpurl":"http://shiranlife.kuaizhan.com/","posflag":4,"remark":"","cityid":1}]}
*/ public int code;
public DataBean data; public static class DataBean {
public List<HomeadlistBean> homeadlist; public static class HomeadlistBean {
public int id;
public String imgurl;
public int jumpflag;
public String jumpurl;
public int posflag;
public String remark;
public int cityid;
}
}
}

我们使用OKHttpClient,代码如下

OkHttpClient.Builder builder = new OkHttpClient.Builder();

        Request request = new Request.Builder()
.url(url)
.get()
.build(); builder.build().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { } @Override
public void onResponse(Call call, Response response) throws IOException {
Gson gson = new Gson();
/**
* java.lang.IllegalStateException: closed
* 因为OkHttp请求回调中response.body().string()只能有效调用一次
*
*/ String string = response.body().string();
Log.i("aaa", "response: " + string);
/**
* 重新构建一个response 因为response.body().string()调用一次之后流就断掉了,只能有效调用一次
*/
MediaType mediaType = response.body().contentType();
Response response1 = response.newBuilder().body(ResponseBody.create(mediaType, string)).build();
String string1 = response1.body().string();
Log.i("aaa", "response1: " + string1);
/**
* 将json数据转换为对象
*/
HomeadListModel model = gson.fromJson(string1, HomeadListModel.class);
//HomeadListModel model2 = gson.fromJson(string1, new TypeToken<HomeadListModel>() {
}.getType());
/**
* 将对象转换为json数据
*/
String jsonString = gson.toJson(model);
Log.i("aaa", "onResponse2: " + jsonString); for (HomeadListModel.DataBean.HomeadlistBean data : model.data.homeadlist) {
mData.add(imageUrl + data.imgurl);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
});

我们想要将一个json数据转换为对象的话需要使用fromJson(String json, Class classOfT) /fromJson(String json, Type typeOfT),当我们需要将对象转换为String的时候根据String toJson(Object src)方法即可。这里需要注意一点,如果response.body().string()调用大于一次的话,就会报错java.lang.IllegalStateException: closed,因为因为response.body().string()调用一次之后流就断掉了,需要重新构建一个response;

  • FastJson解析

这个解析和Gson解析差不多,也是一行就搞定了,也是对上面的Gson数据进行解析,想要将json数据解析成对象需要使用 parseObject()方法,参数可以传Class,也可以传Type;当需要通过对象得到String字符串时候使用String json1 = JSONObject.toJSONString(model)即可,下面贴上代码:

OkHttpClient.Builder builder = new OkHttpClient.Builder();
Request request = new Request.Builder()
.url(url)
.get()
.build();
builder.build().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { } @Override
public void onResponse(Call call, Response response) throws IOException { String json = response.body().string();
/**
* 根据json数据获取对象
*/
HomeadListModel model = JSONObject.parseObject(json, new TypeToken<HomeadListModel>() {
}.getType());
// HomeadListModel model2 = JSONObject.parseObject(json, HomeadListModel.class); /**
* 根据对象获取json数据
*/
String json1 = JSONObject.toJSONString(model);
Log.i("aaa", "fastJson: " + json1); for (HomeadListModel.DataBean.HomeadlistBean data : model.data.homeadlist) {
mData.add(imageUrl + data.imgurl);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
});

结尾:上面写了三种解析JSON数据的方法,第一种是最麻烦的,但是不一定是最差的,后面两种Gson和FastJson都是最常用的方法,本博客里面用到的API也是最常用的API,基本开发都够用了,其余未涉及到的请自行查看源码学习吧。(完)

Java泛型详解

JSON三种数据解析方法(转)的更多相关文章

  1. python网络爬虫数据中的三种数据解析方式

    一.正则解析 常用正则表达式回顾: 单字符: . : 除换行以外所有字符 [] :[aoe] [a-w] 匹配集合中任意一个字符 \d :数字 [0-9] \D : 非数字 \w :数字.字母.下划线 ...

  2. Python爬虫的三种数据解析方式

    数据解析方式 - 正则 - xpath - bs4 数据解析的原理: 标签的定位 提取标签中存储的文本数据或者标签属性中存储的数据 正则 # 正则表达式 单字符: . : 除换行以外所有字符 [] : ...

  3. .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)

    .Net MVC  导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构)   public cl ...

  4. C#-正则,常用几种数据解析-端午快乐

    在等待几个小时就是端午节了,这里预祝各位节日快乐. 这里分享的是几个在C#中常用的正则解析数据写法,其实就是Regex类,至于正则的匹配格式,请仔细阅读正则的api文档,此处不具体说明,谢谢. 开始吧 ...

  5. Excel应该这么玩——5、三种数据:Excel也是系统

        Excel最常用的功能就是记录数据,把数据按照行列记录下来.这部分数据是源数据,是业务活动中最原始的流水账,作为后续操作的依据.为了从源数据中得出一定的结论,需要对源数据进行分析得出报表数据. ...

  6. iOS开发——网络Swift篇&JSON与XML数据解析

    JSON与XML数据解析 JSON数据解析(内置NSJSONSerialization与第三方JSONKit)   一,使用自带的NSJSONSerialization 苹果从IOS5.0后推出了SD ...

  7. iPhone开发 数据持久化总结(终结篇)—5种数据持久化方法对比

    iPhone开发 数据持久化总结(终结篇)—5种数据持久化方法对比   iphoneiPhoneIPhoneIPHONEIphone数据持久化 对比总结 本篇对IOS中常用的5种数据持久化方法进行简单 ...

  8. iOS中常用的四种数据持久化方法简介

    iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...

  9. Hibernate中的三种数据状态

    Hibernate中的三种数据状态(临时.持久.游离) 1.临时态(瞬时态) 不存在于session中,也不存在于数据库中的数据,被称为临时态. 比如:刚刚使用new关键字创建出的对象. 2.持久态 ...

随机推荐

  1. OLW (Open Live Writer)安装代码高亮插件方法(简明)

    1.首先下载OLW代码高亮插件,请点击--->OLW代码高亮插件 2.在你安装OLW的目录下(顺便说一下默认的安装目录为C:\Users\你的用户名\AppData\Local\OpenLive ...

  2. python 词云学习

    词云入门 三步曲 数据获取:使用爬虫在相关网站上获取文本内容 数据清洗:按一定格式对文本数据进行清洗和提取(文本分类,贴标签) 数据呈现:多维度呈现和解读数据(计算,做表,画图) 一 模块的安装 pi ...

  3. 【Linux基础】mount报错:mount.nfs: Remote I/O error

    问题描述:mount 报错:mount.nfs: Remote I/O error 挂载时需要指明版本,由于NFS服务器有多个版本,V2.V3.V4.而且各版本同时运行,因此挂载时需要说明版本号. 由 ...

  4. 【Teradata SQL】字符串分割函数STRTOK和STRTOK_SPLIT_TO_TABLE

    STRTOK函数: 按照指定分隔符,将字符串分割成多个部分,返回指定部分字符串. 参数说明: (1)instring:字符串或字符串表达式. (2)delimiter:分隔符列表,字符串每个字符都会做 ...

  5. Redis学习笔记(4)——Redis五大数据结构介绍以及应用场景

    出处:https://www.jianshu.com/p/f09480c05e42 Redis是典型的Key-Value类型数据库,Key为字符类型,Value的类型常用的为五种类型:String.H ...

  6. LVS负载均衡集群

    回顾-Nginx反向代理型负载 负载均衡(load balance)集群,提供了一种廉价.有效.透明的方法,来扩展网络设备和服务器的负载.带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用 ...

  7. Pyqt5-Python应用开发——第一个小程序的实现

    环境:python 3.6.6 编辑器:pycharm 其他:QtDesigner:Qt Designer,是一个直观可见的全方位 GUI 构造器,它所设计出来的用户界面能够在多种平台上使用.它是 Q ...

  8. 基于winserver的Apollo配置中心分布式&集群部署实践(正确部署姿势)

    基于winserver的Apollo配置中心分布式&集群部署实践(正确部署姿势)   前言 前几天对Apollo配置中心的demo进行一个部署试用,现公司已决定使用,这两天进行分布式部署的时候 ...

  9. Laravel框架下容器Container 的依赖注入和反射应用

    依赖注入,简单说是把类里头依赖的对象,置于类外头,即客户端调用处.相当于把类与类解耦. 一个简单的例子: class A { public function __construct() { // 这种 ...

  10. Activiti开发案例之activiti-app更换数据源

    前言 由于Activiti 默认使用的数据库是H2数据库,重启服务后相关数据会丢失.为了永久保存,所以要配置关系型数据库,这里我们选择 SqlServer ,有钱任性. 环境 Activiti6,Sq ...