Android数据解析JSON解析之手动JSON解析
JSON简介
定义
JSON的全称是JavaScript Object Notation,是一种轻量级的数据交换格式。
JSON 语法是 javascript 语法的子集。
特点
(1)JSON比XML数据传输的有效性要高出很多
(2)JSON完全独立于编程语言。
(3)本质就是具有特定格式的字符串
JSON 语法规则
JSON 语法是 JavaScript 对象表示法语法的子集。
- 数据在名称/值对中 如”firstName” : “John”
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
JSON 值类型
JSON 值可以是:
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true或false)
- 数组(在方括号中)
- 对象(在花括号中)
- null
常用的JSON值类型是:
JSON数组
{
“employees”: [
{ “firstName”:”John” , “lastName”:”Doe” },
{ “firstName”:”Anna” , “lastName”:”Smith” },
{ “firstName”:”Peter” , “lastName”:”Jones” }
]
}
JSON 数组在方括号中书写:
JSON对象
对象可以包含多个名称/值对:
{ “firstName”:”John” , “lastName”:”Doe” }
JSON 对象在花括号中书写
手动JSON解析
1、将JSON 对象转化为Java对象
测试数据
{
"id":2, "name":"大虾",
"price":12.3,
"imagePath":"http://192.168.10.165:8080/L05_Server/images/f1.jpg"
}
代码:
private void jsonToJavaObject() {
//获取json字符串
String jsonData = "{\n" +
"\t\"id\":2, \"name\":\"大虾\", \n" +
"\t\"price\":12.3, \n" +
"\t\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"\n" +
"}";
ShopInfo shopInfo = new ShopInfo();
//解析json
try {
//获取JsonObject对象
JSONObject jsonObject = new JSONObject(jsonData);
/**获取数据
* getInt("key") 取值 不存在 或者类型不对 报错
optInt("key") 取值 不存在 返回默认值
*/
int id = jsonObject.optInt("id");
String name = jsonObject.optString("name");
Double price = jsonObject.optDouble("price");
String imagePath = jsonObject.optString("imagePath");
//封装成Java对象
shopInfo = new ShopInfo(id, name, price, imagePath);
} catch (JSONException e) {
e.printStackTrace();
}
测试效果:
2、将json格式的数组[]转换为Java对象的List集合
测试数据
[
{
"id": 1,
"imagePath": "http://192.168.10.165:8080/f1.jpg",
"name": "大虾1",
"price": 12.3
},
{
"id": 2,
"imagePath": "http://192.168.10.165:8080/f2.jpg",
"name": "大虾2",
"price": 12.5
}
]
代码:
private void jsonToJavaList() {
// a.获取或创建JSON数据
String json = "[\n" +
" {\n" +
" \"id\": 1,\n" +
" \"imagePath\": \"http://192.168.10.165:8080/f1.jpg\",\n" +
" \"name\": \"大虾1\",\n" +
" \"price\": 12.3\n" +
" },\n" +
" {\n" +
" \"id\": 2,\n" +
" \"imagePath\": \"http://192.168.10.165:8080/f2.jpg\",\n" +
" \"name\": \"大虾2\",\n" +
" \"price\": 12.5\n" +
" }\n" +
"]";
// b. 解析json
List<ShopInfo> shops = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
//判断 JSONObject非空,否则无法显示数据
if (jsonObject != null) {
int id = jsonObject.optInt("id");
String name = jsonObject.optString("name");
double price = jsonObject.optDouble("price");
String imagePath = jsonObject.optString("imagePath");
// 封装Java对象
ShopInfo shopInfo = new ShopInfo(id, name, price, imagePath);
//将数组元素添加到Java集合中
shops.add(shopInfo);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
测试效果:
3、复杂json数据解析(json对象里面嵌套数组)
测试数据
{
"data": {
"count": 5,
"items": [
{
"id": 45,
"title": "坚果"
},
{
"id": 132,
"title": "炒货"
},
{
"id": 166,
"title": "蜜饯"
},
{
"id": 195,
"title": "果脯"
},
{
"id": 196,
"title": "礼盒"
}
]
},
"rs_code": "1000",
"rs_msg": "success"
}
代码:
private void jsonToJavaOfComplex() {
// 1 获取或创建JSON数据
String json = "{\n" +
" \"data\": {\n" +
" \"count\": 5,\n" +
" \"items\": [\n" +
" {\n" +
" \"id\": 45,\n" +
" \"title\": \"坚果\"\n" +
" },\n" +
" {\n" +
" \"id\": 132,\n" +
" \"title\": \"炒货\"\n" +
" },\n" +
" {\n" +
" \"id\": 166,\n" +
" \"title\": \"蜜饯\"\n" +
" },\n" +
" {\n" +
" \"id\": 195,\n" +
" \"title\": \"果脯\"\n" +
" },\n" +
" {\n" +
" \"id\": 196,\n" +
" \"title\": \"礼盒\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"rs_code\": \"1000\",\n" +
" \"rs_msg\": \"success\"\n" +
"}";
// 封装Java对象
DataInfo dataInfo = new DataInfo();
// 2 解析json
try {
JSONObject jsonObject = new JSONObject(json);
// 第一层解析,解析JSON对象
JSONObject data = jsonObject.optJSONObject("data");
String rs_code = jsonObject.optString("rs_code");
String rs_msg = jsonObject.optString("rs_msg");
// 第一层封装
dataInfo.setRs_code(rs_code);
dataInfo.setRs_msg(rs_msg);
DataInfo.DataBean dataBean = new DataInfo.DataBean();
dataInfo.setData(dataBean);
// 第二层解析
int count = data.optInt("count");
JSONArray items = data.optJSONArray("items");
// 第二层数据的封装
dataBean.setCount(count);
List<DataInfo.DataBean.ItemsBean> itemsBean = new ArrayList<>();
dataBean.setItems(itemsBean);
// 第三层解析,解析对象中数组
for (int i = 0; i < items.length(); i++) {
JSONObject jsonObject1 = items.optJSONObject(i);
if (jsonObject1 != null) {
int id = jsonObject1.optInt("id");
String title = jsonObject1.optString("title");
// 第三层数据的封装
DataInfo.DataBean.ItemsBean bean = new DataInfo.DataBean.ItemsBean();
bean.setId(id);
bean.setTitle(title);
itemsBean.add(bean);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
测试效果:
4、特殊json数据解析(对象里面嵌套对象)
测试数据:
{
"code": 0,
"list": {
"0": {
"aid": "6008965",
"author": "哔哩哔哩番剧",
"coins": 170,
"copyright": "Copy",
"create": "2016-08-25 21:34"
},
"1": {
"aid": "6008938",
"author": "哔哩哔哩番剧",
"coins": 404,
"copyright": "Copy",
"create": "2016-08-25 21:33"
}
}
}
代码:
private void jsonToJavaOfSpecial() {
// 1 获取或创建JSON数据
String json = "{\n" +
" \"code\": 0,\n" +
" \"list\": {\n" +
" \"0\": {\n" +
" \"aid\": \"6008965\",\n" +
" \"author\": \"哔哩哔哩番剧\",\n" +
" \"coins\": 170,\n" +
" \"copyright\": \"Copy\",\n" +
" \"create\": \"2016-08-25 21:34\"\n" +
" },\n" +
" \"1\": {\n" +
" \"aid\": \"6008938\",\n" +
" \"author\": \"哔哩哔哩番剧\",\n" +
" \"coins\": 404,\n" +
" \"copyright\": \"Copy\",\n" +
" \"create\": \"2016-08-25 21:33\"\n" +
" }\n" +
" }\n" +
"}";
// 创建封装的Java对象
FilmInfo filmInfo = new FilmInfo();
// 2 解析json
try {
JSONObject jsonObject = new JSONObject(json);
// 第一层解析
int code = jsonObject.optInt("code");
JSONObject list = jsonObject.optJSONObject("list");
// 第一层封装
filmInfo.setCode(code);
List<FilmInfo.FilmBean> lists = new ArrayList<>();
filmInfo.setList(lists);
// 第二层解析
for (int i = 0; i < list.length(); i++) {
JSONObject jsonObject1 = list.optJSONObject(i + "");
if (jsonObject1 != null) {
String aid = jsonObject1.optString("aid");
String author = jsonObject1.optString("author");
int coins = jsonObject1.optInt("coins");
String copyright = jsonObject1.optString("copyright");
String create = jsonObject1.optString("create");
// 第二层数据封装
FilmInfo.FilmBean filmBean = new FilmInfo.FilmBean();
filmBean.setAid(aid);
filmBean.setAuthor(author);
filmBean.setCoins(coins);
filmBean.setCopyright(copyright);
filmBean.setCreate(create);
lists.add(filmBean);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
测试效果:
总结:
对于手动JSON解析来说,解析的过程无疑就是碰到大括号,就new一个Object出来,通过JSONObject.opt…()或者JSONObject.get…()方法获取数据;碰到中括号就new一个Array出来,再用一个for循环,通过通JSONObject.opt…方法,获取数据。
测试Demo地址
github:https://github.com/TDCQZD/AndroidJson