JSON 
1.1、JSON简介
short for:JavaScript Object Notation
是什么 ?:a lightweight, text-based, easy for humans to read and write, easy for machines to parse and generate, language-independent syntax for defining data interchange formats. It was derived from the JavaScript Programming Language Standard ECMA-262 3rd Edition - December 1999, but is programming language independent. JSON defines a small set of structuring rules for the portable representation of structured data.
相关标准:RFC4627ECMA-404
相关资源:https://www.json.org

JSON是把JavaScript中的Object进行了字符串化,使得它便于在网络中传输。

1.2、JSON的数据类型与常用语言的对应关系
JSON示例JavaScriptJavaObjective-C
JSONObject{key1:value1, key2:value2, ...}ObjectMapNSDictionary
JSONArray[value1, value2, ...]ArrayArrayListNSArray
string"xxx"、""、nullStringStringNSString
integer10、-10Numberint、longNSInteger
float10.0、-10.0Numberfloat、doubleCGFloat
truetruetruetrueYES
falsefalsefalsefalseNO
nullnullnullnullNSNull
1.2.1、JSONObject

JSONObject就是用{}扩起来的key-value对形式的数据。 这种结构在不同的语言中有不同的叫法,比如: 在Objective-C中称为NSDictionary, 在Java中称为Map, 在JavaScript里就是叫做Object

JSONObject中的key都是字符串,字符串只能使用双引号扩起来,不能使用单引号扩起来。这一点要特别注意, 虽然JSON源于JavaScript,在JavaScript里, 字符串既可以使用双引号扩起来,也允许使用单引号扩起来,但是绝大多数语言里不允许字符串使用单引号扩起来的,所以,为了兼容性,这里规定,字符串必须使用双引号扩起来。value可以是任意类型。

示例:

{
	"username": "fpliu",
	"age": 18,
	"height": 180.5,
	"married": false,
	"male": true,
	"motion": null,
	"phones": ["156565059398", "156565059399"]
}
1.2.2、JSONArray

JSONArray就是数组,这在不同的语言里的中文称呼都是一样的。

JSONArray里可以放任意相同数据类型的数据。

示例:

[
    {
        "username": "fpliu",
        "age": 18,
        "height": 180.5,
        "married": false,
        "male": true,
        "motion": null,
        "phones": ["156565059398", "156565059399"]
    },
    {
        "username": "fpliu",
        "age": 18,
        "height": 180.5,
        "married": false,
        "male": true,
        "motion": null,
        "phones": ["156565059398", "156565059399"]
    }
]
1.2.3、string

string就是字符串,这在不同的语言里的中文称呼都是一样的。

考虑到大部分语言都支持Unicode字符集和UTF-8字符编码。而且不同的语言可能对一些特殊的字符做特殊的处理,所以,JSON规定:下面的字符需要做转义处理:

字符Unicode Code Point( 十进制)转义后
"34\"
\92\\
/47\/
\b8\\b
\f12\\f
\t9\\t
\r13\\r
\n10\\n
非BMP\uxxxx\uyyyy

这里要特别注意的是:对于Code Point为非BMP内的对应字符,需要把他们拆分成两个字符来看待, 比如:U+1F604这个Code Point对应于这个emoji, 我们转义的时候,不能转成\u1F604,而是要转成\ud83d\ude04

Java语言对转义的处理示例:

private static String escapeJSONString(String value) {
    if (value == null || value == "") return value;
    StringBuilder stringBuilder = new StringBuilder();
    int length = value.length();
    for (int i = 0; i < length; i++) {
        char ch = value.charAt(i);
        switch (ch) {
            case '"': stringBuilder.append("\\\"");break;
            case '\\': stringBuilder.append("\\\\");break;
            case '/': stringBuilder.append("\\/");break;
            case '\t': stringBuilder.append("\\t");break;
            case '\r': stringBuilder.append("\\r");break;
            case '\n': stringBuilder.append("\\n");break;
            case '\b': stringBuilder.append("\\b");break;
            case '\f': stringBuilder.append("\\f");break;
            default: {
                if ((ch >= 0xD800 && ch <= 0xDBFF)
                    || (ch >= 0xDC00 && ch <= 0xDFFF)) {
                    stringBuilder.append("\\u").append(Integer.toHexString(ch));
                } else {
                    stringBuilder.append(ch);
                }
            }
        }
    }
    return stringBuilder.toString();
}

一个合法的JSON示例:

{
    "a": "\"",
    "b": "\\",
    "c": "\/",
    "d": "\b",
    "e": "\f",
    "f": "\t",
    "g": "\r",
    "h": "\n",
    "i": "\ud83d\ude04"
}
1.2.4、Number

Number就是十进制的数字,其实就是数学中的实数。实数分为整数和小数,而且有正、负之分。 对应于计算机编程语言中的整数和浮点数。

Number也允许使用科学计数法,规则是:[-]<number><e|E>[+|-]<exp>, 这里的e或者E表示的是10的幂的意思。

这个要特别注意:标准里并没有说这个数的范围,从理论上说是可以无限大的,在使用的过程中要考虑不同语言对于数字支持的最大数进行考虑。

示例:

{
    "a": 100,
    "b": 1e2,
    "c": 1E2,
    "d": 0.1,
    "e": 1e-1,
    "f": 1E-1
    "g": -0.25,
    "h": -2.5e-1,
    "i": -2.5E-1
}
1.2.5、Boolean

Boolean类型只有两个字面量:truefalse。 这个要注意的是:都是小写字母,而且不要用双引号扩起来,否则就变成了字符串了。

示例:

{
    "isMarried": false,
    "male": true
}
1.2.6、null

null这个关键字在很多语言里都存在,通常的意思是指引用不存在,在JavaJavaScript里经常使用。 但是在其他语言里未必存在这个关键字,比如CC++语言里就没有这个关键字, 它等同于CC++语言里的NULLObjective-C里也没有这个关键字, 它等同于Objective-C里的NSNull,而不是nil

JSONObjectJSONArraystring都允许取值为null

示例:

{
    "data": null
}
1.3、在线格式化和校验合法性

http://www.bejson.com

1.4、解析JSON

https://www.json.org里罗列了各种语言实现的JSON解析工具,非常多,下面是一些常用的JSON解析库:

C
Objective-C