JSON 指 JavaScript 对象表示法(JavaScript Object Notation),是一种轻量级的数据交换格式,用于存储和交换文本信息。JSON 采用了类似 C 语言家族的习惯,易于人阅读和编写,同时也易于机器解析和生成。
JSON 在用途上类似 XML,但比 XML 更小、更快,更易解析。
JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。目前很多动态编程语言(如 PHP、JSP、.NET)都支持 JSON。
JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。
由于这种相似性,无需解析器,JavaScript 程序能够使用内置的 eval()
函数,用 JSON 数据来生成原生的 JavaScript 对象。
JSON 是一种轻量级的基于文本的开放标准,被设计用于可读的数据交换。约定使用 JSON 的程序包括 C、C++、Java、Python、Perl 等等。
鉴于书籍数据有语言和版本信息,下面的例子展示了使用 JSON 存储书籍信息:
{
"book": [
{
"id": "01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
},
{
"id": "07",
"language": "C++",
"edition": "second",
"author": "E.Balagurusamy"
}
]
}
eval()
方法进行解析。对于 AJAX 应用程序来说,JSON 比 XML 更快更易使用:
使用 XML
使用 JSON
eval()
处理 JSON 字符串。JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。
JSON 的语法基本上可以视为 JavaScript 语法的一个子集,包括以下内容:
:
,名称-值对之间使用逗号 ,
分隔。,
分隔。下面是一个简单的示例:
{
"book": [
{
"id": "01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
},
{
"id": "07",
"language": "C++",
"edition": "second",
"author": "E.Balagurusamy"
}
]
}
JSON 支持以下两种数据结构:
JSON 语法是 JavaScript 对象表示法语法的子集。
JSON 语法规则不复杂,它参考了 C 语言家族的一些习惯,学习起来并不会感到陌生。
JSON 数据的书写格式是:名称-值对。
名称-值对包括字段名称(在双引号中),后面跟一个冒号,然后是值:
"firstName" : "John"
这很容易理解,等价于这条 JavaScript 语句:
firstName = "John"
JSON 值可以是:
JSON 对象在花括号中书写。对象可以包含多个名称-值对:
{
"firstName": "John",
"lastName": "Doe"
}
这一点也容易理解,与这条 JavaScript 语句等价:
firstName = "John";
lastName = "Doe";
JSON 数组在方括号中书写。数组可包含多个对象:
{
"employees": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Anna",
"lastName": "Smith"
},
{
"firstName": "Peter",
"lastName": "Jones"
}
]
}
在上面的例子中,对象“employees”是包含三个对象的数组。每个对象代表一条关于某人(有姓和名)的记录。
执行如下命令即可:
String myObjectInJSON = myObject.toJSONString();
JSON 格式支持以下数据类型:
类型 | 描述 |
---|---|
数字型(Number) | JavaScript 中的双精度浮点型格式 |
字符串型(String) | 双引号包裹的 Unicode 字符和反斜杠转义字符 |
布尔型(Boolean) | true 或 false |
数组(Array) | 有序的值序列 |
值(Value) | 可以是字符串、数字、true 或 false、null 等等 |
对象(Object) | 无序的名称-值对集合 |
空格(Whitespace) | 可用于任意符号对之间 |
null | 空 |
下表展示了数字类型:
类型 | 描述 |
---|---|
整型(Integer) | 数字 1~9,0 和正负数 |
分数(Fraction) | 分数,比如 .3、.9 |
指数(Exponent) | 指数,比如 e,e+,e-,E,E+,E- |
语法
var json-object-name = { string : number_value, … }
示例
下面的示例展示了数字类型,其值不应该使用引号包裹:
var obj = {marks: 97}
下表展示了字符串类型:
类型 | 描述 |
---|---|
" | 双引号 |
\ | 反斜杠 |
/ | 斜杠 |
\b | 退格符 |
\f | 换页符 |
\n | 换行符 |
\r | 回车符 |
\t | 水平制表符 |
\u | 四位十六进制数字 |
语法
var json-object-name = { string : "string value", … }
示例
下面的示例展示了字符串数据类型:
var obj = {name: 'Amit'}
它包含 true 和 false 两个值。
语法
var json-object-name = { string : true/false, … }
示例
var obj = { name: 'Amit', marks: 97, distinction: true }
[
开始,以 ]
结尾。,
分割。语法
[ value, … ]
示例
下面的示例展示了一个包含多个对象的数组:
{
"books": [
{
"language": "Java",
"edition": "second"
},
{
"language": "C++",
"lastName": "fifth"
},
{
"language": "C",
"lastName": "third"
}
]
}
{
开始,以 }
结尾。:
,名称-值对使用逗号 ,
分隔。语法
{ string : value, … }
示例
下面的例子展示了对象:
{
"id": "011A",
"language": "JAVA",
"price": 500,
}
可以在任意一对符号之间插入。可以添加用来让代码更可读。下面的例子展示了使用空格和不使用空格的声明:
语法
{ string : " ", … }
示例
var i = " sachin";
var j = " saurav";
意味着空类型。
语法
null
示例
var i = null;
if (i == 1) {
document.write("value is 1
");
} else {
document.write("value is null
");
}
JSON 包含两种基础结构:
无序的对象结构
无序的对象结构在不同语言中称法不同,比如在 Python 中称为字典,在 JSON 中称为 JSON 对象……
总之就是键-值对组合形式。
有序的数组结构
将数组作为有序数组进行转换 JSON,就可以得到有序的 JSON 数组结构。
JSON 模式(Schema)是一种基于 JSON 格式定义 JSON 数据结构的规范。JSON 模式:
下面是一个基本的 JSON 模式,其中涵盖了一个经典的产品目录说明:
{
"$schema": "https://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"name": {
"description": "Name of the product",
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
}
},
"required": ["id", "name", "price"]
}
我们来看一下可以用于这一模式中的各种重要关键字:
关键字 | 描述 |
---|---|
$schema |
$schema 关键字状态,表示这个模式与 v4 规范草案书写一致。 |
title |
用它给我们的模式提供了标题。 |
description |
关于模式的描述。 |
type |
type 关键字在我们的 JSON 数据上定义了第一个约束:必须是一个 JSON 对象。 |
properties |
定义各种键和它们的值类型,以及用于 JSON 文件中的最小值和最大值。 |
required |
存放必要属性列表。 |
minimum |
给值设置的约束条件,表示可以接受的最小值。 |
exclusiveMinimum |
如果存在 exclusiveMinimum 并且具有布尔值 true,如果它严格意义上大于 minimum 的值则实例有效。 |
maximum |
给值设置的约束条件,表示可以接受的最大值。 |
exclusiveMaximum |
如果存在 exclusiveMinimum 并且具有布尔值 true,且它严格意义上小于 maximum 的值则实例有效。 |
multipleOf |
如果通过这个关键字的值分割实例的结果是一个数字则表示紧靠 multipleOf 的数字实例是有效的。 |
maxLength |
字符串实例字符的最大长度数值。 |
minLength |
字符串实例字符的最小长度数值。 |
pattern |
如果正则表达式匹配实例成功则字符串实例被认为是有效的。 |
可以在 JSON Schema 上检出可用于定义 JSON 模式的完整关键字列表。上面的模式可用于测试下面给出的 JSON 代码的有效性:
[
{
"id": 2,
"name": "An ice sculpture",
"price": 12.50,
},
{
"id": 3,
"name": "A blue mouse",
"price": 25.50,
}
]
JSON 常见的应用场景是:在后台应用程序中将响应数据封装成 JSON 格式,传到前台页面之后,需要将 JSON 格式转换为 JavaScript 对象,然后在网页中使用该数据。
JSON 最常见的用法之一,是从 Web 服务器上读取 JSON 数据(作为文件或 HttpRequest),将 JSON 数据转换为 JavaScript 对象,然后在网页中使用该数据。
下面使用字符串作为输入进行演示(而不是文件)。
创建包含 JSON 语法的 JavaScript 字符串:
var txt = '{"employees": [' +
'{"firstName" : "John", "lastName" : "Doe"}, ' +
'{"firstName" : "Anna", "lastName" : "Smith"}, ' +
'{"firstName" : "Peter", "lastName" : "Jones"} ]}';
由于 JSON 语法是 JavaScript 语法的子集,JavaScript 函数 eval()
可用于将 JSON 文本转换为 JavaScript 对象。
eval()
函数使用的是 JavaScript 解释器,可解析 JSON 文本,然后生成 JavaScript 对象。必须把文本包围在括号中,这样才能避免语法错误:
var obj = eval ("(" + txt + ")");
eval()
函数可解释执行任何 JavaScript 代码。这隐藏了一个潜在的安全问题。
使用 JSON 解析器将 JSON 转换为 JavaScript 对象是更安全的做法。JSON 解析器只能识别 JSON 文本,而不会解释脚本。
浏览器提供了原生的 JSON 支持,而且 JSON 解析器的速度更快。
JSONP(JSON with Padding)是 JSON 的一种“使用模式”,可以让网页从别的域名(网站)获取资料,即跨域读取数据。
为什么我们从不同的域(网站)访问数据需要一个特殊的技术(JSONP)呢?这是因为同源策略。
同源策略是由网景提出的一个著名的安全策略,现在所有支持 JavaScript 的浏览器都会使用这个策略。
JSONP 的实现原理是利用 标签可以获取不同源资源的特点,来达到跨域访问某个资源的目的。
服务端 JSONP 格式数据
如客户想访问 : /try/ajax/jsonp.php?jsonp=callbackFunction。
假设客户期望返回 JSON 数据:["customername1", "customername2"]。
真正返回到客户端的数据显示为:callbackFunction(["customername1", "customername2"])。
服务端文件 jsonp.php 代码为:
客户端实现 callbackFunction() 函数
页面展示
客户端页面完整代码
JSONP 实例
以上代码可以使用 jQuery 代码实例:
JSONP 实例
先准备环境以便针对 JSON 进行 Python 编程。
在我们使用 Python 编码和解码 JSON 之前,我们需要安装一个可用 JSON 模块。我们采用 Demjson:
$tar xvfz demjson-1.6.tar.gz
$cd demjson-1.6
$python setup.py install
函数 | 程序库 |
---|---|
encode() |
将 Python 对象编码为 JSON 字符串表示。 |
decode() |
将 JSON 编码的字符串解码为 Python 对象。 |
Python 的 encode()
函数用于将 Python 对象编码为 JSON 字符串表示。
语法
demjson.encode(self, obj, nest_level = 0)
示例
下面的例子展示了使用 Python 将数组转换为 JSON:
#!/usr/bin/python
import demjson
data = [ { 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 } ]
json = demjson.encode(data)
print json
执行时会生成如下结果:
[{"a":1,"b":2,"c":3,"d":4,"e":5}]
Python 可以使用 demjson.decode()
函数处理 JSON 解码。这个函数返回从 JSON 解码到适当 Python 类型的值。
语法
demjson.decode(self, txt)
示例
下面的例子展示了如何使用 Python 解码 JSON 对象。
#!/usr/bin/python
import demjson
json = '{"a":1,"b":2,"c":3,"d":4,"e":5}'
text = demjson.decode(json)
print text
执行时生成如下结果:
{u'a': 1, u'c': 3, u'b': 2, u'e': 5, u'd': 4}
先准备环境以便针对 JSON 进行 Java 编程。
在我们使用 Java 编码和解码 JSON 之前,我们需要安装一个可用的 JSON 模块。我们采用 JSON.simple,然后导入 jsonsimple-1.1.1.jar 。
JSON.simple 实体映射从左侧到右侧为解码或解析,实体映射从右侧到左侧为编码。
JSON | Java |
---|---|
字符串 | java.lang.String |
数字 | java.lang.Number |
bool | java.lang.Boolean |
null | null |
数组 | java.util.List |
对象 | java.util.Map |
解码时,java.util.List
的默认具体类是 org.json.simple.JSONArray
,java.util.Map
的默认具体类是 org.simple.JSONObject
。
下面这个简单的示例展示了使用 java.util.HashMap
的子类 JSONObject
编码一个 JSON 对象。这里并没有提供顺序。如果需要严格的元素顺序,请使用 JSONValue.toJSONString(map)
方法的有序映射实现,比如 java.util.LinkedHashMap
。
import org.json.simple.JSONObject;
class JsonEncodeDemo
{
public static void main(String[] args)
{
JSONObject obj = new JSONObject();
obj.put("name", "foo");
obj.put("num", new Integer(100));
obj.put("balance", new Double(1000.21));
obj.put("is_vip", new Boolean(true));
System.out.print(obj);
}
}
生成如下结果:
{"balance": 1000.21, "num":100, "is_vip":true, "name":"foo"}
下面是另一个示例,使用 Java JSONObject 展示了 JSON 对象流:
import org.json.simple.JSONObject;
class JsonEncodeDemo
{
public static void main(String[] args)
{
JSONObject obj = new JSONObject();
obj.put("name", "foo");
obj.put("num", new Integer(100));
obj.put("balance", new Double(1000.21));
obj.put("is_vip", new Boolean(true));
StringWriter out = new StringWriter();
obj.writeJSONString(out);
String jsonText = out.toString();
System.out.print(jsonText);
}
}
生成如下结果:
{"balance": 1000.21, "num":100, "is_vip":true, "name":"foo"}
下面的例子使用了 JSONObject
和 JSONArray
,其中 JSONObject
就是 java.util.Map
,JSONArray
就是 java.util.List
,因此我们可以使用 Map 或 List 的标准操作访问它们。
import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
import org.json.simple.parser.ParseException;
import org.json.simple.parser.JSONParser;
class JsonDecodeDemo
{
public static void main(String[] args)
{
JSONParser parser=new JSONParser();
String s = "[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]";
try {
Object obj = parser.parse(s);
JSONArray array = (JSONArray)obj;
System.out.println("The 2nd element of array");
System.out.println(array.get(1));
System.out.println();
JSONObject obj2 = (JSONObject)array.get(1);
System.out.println("Field \"1\"");
System.out.println(obj2.get("1"));
s = "{}";
obj = parser.parse(s);
System.out.println(obj);
s= "[5,]";
obj = parser.parse(s);
System.out.println(obj);
s= "[5,,2]";
obj = parser.parse(s);
System.out.println(obj);
} catch(ParseException pe) {
System.out.println("position: " + pe.getPosition());
System.out.println(pe);
}
}
}
生成如下结果:
The 2nd element of array
{"1":{"2":{"3":{"4":[5,{"6":7}]}}}}
Field "1"
{"2":{"3":{"4":[5,{"6":7}]}}}
{}
[5]
[5,2]