1.JSON是什么
JSON 是一种用于数据交换的文本格式,诞生于 2001 年由Douglas Crockford提出,目的是取代繁琐笨重的XML格式。这种格式不仅人很容易进行阅读和编写,同时机器也很容易解析和生成,是当前十分流行的数据格式,尤其是在前端领域。
JSON,全称是 JavaScript Object Notation,即 JavaScript 对象标记法。这是一种 轻量级 (Light-Weight)、 基于文本的 (Text-Based)、 可读的 (Human-Readable)格式。
JSON 无论对于人,还是对于机器来说,都是十分便于阅读和书写的,而且相比 XML 文件更小;
JSON 格式的创始人声称此格式永远不升级,这就表示这种格式具有长时间的稳定性;
JSON格式有两个显著的优点:书写简单,一目了然;符合JavaScript原生语法,可以由解释引擎直接处理,不用另外添加解析代码。
JSON已经成为各大网站交换数据的标准格式,并被写入ECMAScript 5,成为标准的一部分。
简单说,每个JSON对象,就是一个值。要么是简单类型的值,要么是复合类型的值,但是只能是一个值,不能是两个或更多的值。这就是说,每个JSON文档只能包含一个值。
2.JSON有哪两种结构
1、对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种:
名称\值对
按照最简单的形式,可以用下面这样的 JSON 表示"名称 / 值对":
1
|
{"firstName":"Brett"}
|
1
|
firstName=Brett
|
1
|
{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"}
|
2、数组:数组在js中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种:
1
2
3
4
5
6
7
|
{
"people":[
{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},
{"firstName":"Jason","lastName":"Hunter","email":"bbbb"},
{"firstName":"Elliotte","lastName":"Harold","email":"cccc"}
]
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
{
"programmers": [{
"firstName": "Brett",
"lastName": "McLaughlin",
"email": "aaaa"
}, {
"firstName": "Jason",
"lastName": "Hunter",
"email": "bbbb"
}, {
"firstName": "Elliotte",
"lastName": "Harold",
"email": "cccc"
}],
"authors": [{
"firstName": "Isaac",
"lastName": "Asimov",
"genre": "sciencefiction"
}, {
"firstName": "Tad",
"lastName": "Williams",
"genre": "fantasy"
}, {
"firstName": "Frank",
"lastName": "Peretti",
"genre": "christianfiction"
}],
"musicians": [{
"firstName": "Eric",
"lastName": "Clapton",
"instrument": "guitar"
}, {
"firstName": "Sergei",
"lastName": "Rachmaninoff",
"instrument": "piano"
}]
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
var people = {
"programmers": [{
"firstName": "Brett",
"lastName": "McLaughlin",
"email": "aaaa"
}, {
"firstName": "Jason",
"lastName": "Hunter",
"email": "bbbb"
}, {
"firstName": "Elliotte",
"lastName": "Harold",
"email": "cccc"
}],
"authors": [{
"firstName": "Isaac",
"lastName": "Asimov",
"genre": "sciencefiction"
}, {
"firstName": "Tad",
"lastName": "Williams",
"genre": "fantasy"
}, {
"firstName": "Frank",
"lastName": "Peretti",
"genre": "christianfiction"
}],
"musicians": [{
"firstName": "Eric",
"lastName": "Clapton",
"instrument": "guitar"
}, {
"firstName": "Sergei",
"lastName": "Rachmaninoff",
"instrument": "piano"
}]
};
|
1
|
people.programmers[0].lastName;
|
1
2
3
|
people.authors[1].genre
// Value is "fantasy"
people.musicians[3].lastName
// Undefined. This refers to the fourth entry, and there isn't one
people.programmers[2].firstName
// Value is "Elliotte"
|
修改数据
1
|
people.musicians[1].lastName=
"Rachmaninov"
;
|
JSON嵌套格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
{
id:
'100000'
,
text:
'廊坊银行总行'
,
children: [
{
id:
'110000'
,
text:
'廊坊分行'
,
children: [
{
id:
'113000'
,
text:
'廊坊银行开发区支行'
,
leaf:
true
},
{
id:
'112000'
,
text:
'廊坊银行解放道支行'
,
children: [
{
id:
'112200'
,
text:
'廊坊银行三大街支行'
,
leaf:
true
},
{
id:
'112100'
,
text:
'廊坊银行广阳道支行'
,
leaf:
true
}
]
},
{
id:
'111000'
,
text:
'廊坊银行金光道支行'
,
leaf:
true
}
]
}
]
}
|
具体形式
编辑
1
2
3
4
|
{
"姓名":"大憨",
"年龄":24
}
|
1
2
3
4
5
6
|
{
"学生": [
{"姓名":"小明","年龄":23},
{"姓名":"大憨","年龄":24}
]
}
|
3.如何解析JSONObject(附案例)
在Unity游戏开发中,使用Newton.Json来反序列化时,需要指定确定的类型,这会带来什么问题?
在游戏的道具系统中,有一个父类Item类,包含属性ID和Name,有一个子类Consumable消耗品类,包含属性HP和MP,UML如下:
后端返回的物品信息Json如下:
[ { "id": 1, "name": "血瓶", "type": "Consumable", "hp": 10, "mp": 0, }, { "id": 2, "name": "蓝瓶", "type": "Consumable", "hp": 0, "mp": 10, } ]
使用Newton.Json时,代码如下:
// itemsJson是包含了物品信息的Json字符串 public void ParseItemJson(string itemsJson) { List<Item> itemList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Item>>(itemsJson); foreach (Item temp in itemList) { int id = temp.ID; string name = temp.Name; Item.ItemType type = temp.Type; Item item = null; switch (type) { case Item.ItemType.Consumable: Consumable consumable = temp as Consumable; int hp = consumable.HP; int mp = consumable.MP; item = new Consumable(id, name, type, hp, mp); break; // 其他类型省略。。。 default: break; }
itemList.Add(temp); } }
按照以上思路,先以Item类型来反序列化,然后根据Item.Type来判断物品类的具体子类型,如果为Consumable消耗品类型,就获取该类型的HP和MP属性,再按消耗品类型来实例化对象。
但是由于反序列化时指定为Item类型,所以即便Json字符串中包含了HP和MP的内容,也不会被解析到Item对象身上。
private List<Item> itemList = new List<Item>(); /// <summary> /// 解析物品Json /// </summary> public void ParseItemJson(string itemsJson) { JSONObject j = new JSONObject(itemsJson); foreach (JSONObject temp in j.list) { int id = (int)temp["id"].n; string name = temp["name"].str; Item.ItemType type = (Item.ItemType)System.Enum.Parse(typeof(Item.ItemType), temp["type"].str); Item item = null; switch (type) { case Item.ItemType.Consumable: int hp = (int)temp["hp"].n; int mp = (int)temp["mp"].n; item = new Consumable(id, name, type, hp, mp); break; // 其他类型省略 default: break; }
Debug.Log("item.id = " + item.ID + " , consumable.hp = " + ((Consumable)item).HP); itemList.Add(item); } }
import java.util.List; public class Teacher { private String name; private String sex; private int age; private List<Transport> myTool; public Teacher(){ } public Teacher(String name,String sex,int age,List<Transport> myTool){ this.name = name; this.sex = sex; this.age = age; this.myTool = myTool; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List<Transport> getMyTool() { return myTool; } public void setMyTool(List<Transport> myTool) { this.myTool = myTool; } }
4.如何解析JSONArray(附案例)
(1)基本使用:
package com.snnu.json; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class demo_JsonArray { public JSONObject testJsonArray(){ JSONObject ob=new JSONObject(); JSONArray ja=new JSONArray(); ja.add("1"); ja.add("2"); ja.add("3"); ja.add("4"); ja.add("5"); ob.put("array", ja); return ob; } public static void main(String[] args) { // TODO Auto-generated method stub demo_JsonArray djs=new demo_JsonArray(); System.out.println("JSONArray的使用:"+djs.testJsonArray()); } }
对输出后的字符串进行格式化:
{ "array": [ "1", "2", "3", "4", "5" ] }
三、综合实例
package com.snnu.json; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class demo_testJson { public JSONObject test(){ JSONObject jo=new JSONObject(); jo.put("name", "张三"); jo.put("sex","f"); jo.put("age",21); Transport bike=new Transport("bike",250); jo.put("extra", bike); Transport car=new Transport("car",10000); jo.accumulate("extra", car); Transport motor=new Transport("motor",3000); jo.accumulate("extra", motor); System.out.println(jo); //根据key值(为extra)取对应的value String value=jo.getString("extra"); System.out.println(value); //将字符串转化为JSONArray JSONArray jsar=JSONArray.fromObject(value); String str_2=String.valueOf(jsar.get(1)); System.out.println(str_2); //将字符串转化为JSONObject JSONObject jsob=JSONObject.fromObject(str_2); System.out.println("名称:"+jsob.getString("name")); System.out.println("价钱:"+jsob.getString("price")); System.out.println("-------------------------------分界线-------------------------------------------"); return jo; } public static void main(String[] args) { // TODO Auto-generated method stub demo_testJson dtj=new demo_testJson(); System.out.println("综合测试:"+dtj.test()); } }
输出结果为:
{"name":"张三","sex":"f","age":21,"extra":[{"name":"bike","price":250},{"name":"car","price":10000},{"name":"motor","price":3000}]} [{"name":"bike","price":250},{"name":"car","price":10000},{"name":"motor","price":3000}] {"name":"car","price":10000} 名称:car 价钱:10000 -------------------------------分界线------------------------------------------- 综合测试:{"name":"张三","sex":"f","age":21,"extra":[{"name":"bike","price":250},{"name":"car","price":10000},{"name":"motor","price":3000}]}