你的位置:首页 > Java教程

[Java教程]JSON的解析和序列化


背景:

 

一.JSON为JavaScript子集,可以使用eval解析JSON字符串,并返回JS对象/JS数组

var data = [  {name: "小明", sex:1, age: 30},  {name: "李雷", sex:0, age: 20},  {name: "熊二", sex:1, age: 30}];//data对象的JSON字符串表示形式var dataJSONText = "[{'name': '小明', 'sex':1, 'age': 30},{'name': '李雷', 'sex':0, 'age': 20},{'name': '熊二', 'sex':1, 'age': 30}]";console.log(eval("("+dataJSONText+")"));//即为data对象

需要注意的是对象在JSON字符串中表现形式的差异性(对象的属性必须加双引号,这在JSON中是必须的!)

 
//JavaScript对象在JSON中的表示形式: var person = {   name:"Nicholas",   age:29 }; //JSON表示上述对象: {   "name":"Nicholas",   "age":29 }

 

二.JSON虽然为JavaScript子集,但还是具有些差异性

  • 1.JSON不支持JavaScript中的特殊值undefined,但支持null
  • 2.JSON不支持变量、函数或对象实例

     

    三.全局JSON对象

    早期使用eval()函数进行JSON字符串的解析,后来ECMAScript5对解析JSON进行规范,定义了全局对象JSON,现在的浏览器基本都支持这个对象。

    JSON对象存在两种方法:

  • JSON.stringify()序列化js对象为JSON字符串

JSON.parse()将JSON字符串解析为JS对象

例1.基本应用:

var data = [  {name: "小明", sex:1, age: 30},  {name: "李雷", sex:0, age: 20},  {name: "熊二", sex:1, age: 30}];//1.js对象序列化为json字符串var str_json = JSON.stringify(data);//2.json字符串解析为原生js对象var data_copy = JSON.parse(str_json);

四.JSON.stringify序列化

JSON.stringify()还可以接收另外两个参数:第一个参数是过滤器、第二个参数是选项(是否在JSON字符串中保留缩进)

1.第一个参数是过滤器:

测试数据1:

//json对象转js对象,右侧为json对象var data=[  {    "LBLCN": "事项",    "FTYPE": "options",    "TOOLTIP": "请选择事项",    "REQD": false,    "EDIT": "EVERYONE",    "ITMS": [      {        "VAL": "选项 1"      },      {        "VAL": "选项 2"      },      {        "VAL": "选项 3"      }    ],    "DEF": ""  },  {    "LBLCN": "明细子表",    "FTYPE": "detailTable",    "FIELDS": [      {        "LBLCN": "多行文本",        "FTYPE": "textarea",        "TOOLTIP": "",        "REQD": false,        "EDIT": "EVERYONE"      },      {        "LBLCN": "事项",        "FTYPE": "options",        "TOOLTIP": "请选择事项",        "REQD": false,        "EDIT": "EVERYONE",        "ITMS": [          {            "VAL": "选项 1"          },          {            "VAL": "选项 2"          },          {            "VAL": "选项 3"          }        ],        "DEF": ""      }    ],    "SCU": "pub"  }]

过滤器是数组:

例2.

  //此时也要使VAL属性对应的上级属性ITMS也要显示,否则VAL显示不出来  console.log(JSON.stringify(data,["VAL","FTYPE"]));  //上级属性ITMS和下级属性VAL的先后顺序不会对过滤产生影响  console.log(JSON.stringify(data,["ITMS","VAL","FTYPE"]));  console.log(JSON.stringify(data,["VAL","ITMS","FTYPE"]));  //同级属性FTYPE和ITMS的先后顺序,会影响过滤结果的先后顺序  console.log(JSON.stringify(data,["FTYPE","VAL","ITMS"]));

测试数据2:

var book = {  title:"Professional JavaScript",  authors:[    "Nicholas C. Zakas"  ],  edition:3,  year:2011};

过滤器是函数:

例3.

var jsonText = JSON.stringify(book, function(key, value) {  switch (key) {  case "authors":    return value.join(",");    //将数组连接成一个字符串  case "year":    return 5000;  case "edition":    return undefined;    //通过返回undefined删除该属性  default:    return value;    //其他属性正常序列化  }});console.log(jsonText);//{"title":"Professional JavaScript","authors":"Nicholas C. Zakas","year":5000}
函数参数为属性名(key)和属性值,根据属性名可以知道如何处理序列化中的属性,并且属性名只能是字符串。注意:当并非键值对结构时,键名可以是空字符串!(实际上第一次调用函数过滤器,传入的键是空字符串,而值是book对象!)
例4.
var data = {  "LBLCN": "事项",  "FTYPE": "options",  "TOOLTIP": "请选择事项",  "REQD": false,  "EDIT": "EVERYONE",  "ITMS": [  "选项 1",   "选项 2",   "选项 3"  ],  "DEF": ""}var dataText = JSON.stringify(data, function(key, value) {  switch (key) {  case "ITMS":    {      var f = [];      //js  for/in      for (i in value) {        f.push({          "VAL": value[i]        });      }      return f;    }  case "VAL":    return value + "test";  default:    return value;  }}, 4);console.log(dataText);

image

过滤原则:要序列化对象中的每一个对象都要经过过滤器函数(即使是转换后的对象,其属性和值也都要经过过滤)

2.第二个参数为字符串缩进

例4.

var book = {  title:"Professional JavaScript",  authors:[    "Nicholas C. Zakas"  ],  edition:3,  year:2011};jsonText = JSON.stringify(book,null,4);//使得JSON字符串包含缩进空格和换行符,增强可读性jsonText = JSON.stringify(book,null,"--");//"--"作为缩进符

image

 

五.toJSON

若JSON.stringify()还无法满足对某些对象自定义序列化的需求,可通过每个对象可以自定义toJSON方法,实现自己的序列化方式,toJSON作为函数过滤器的补充。

例5.

  //Date 有自己的toJSON方法,返回值为字符串。故该对象将被序列化为一个简单字符串而非对象  var date = new Date();  console.log(date.toJSON());//2015-09-12T09:03:00.318Z

重难点:序列化对象的顺序(1.对象有自身的toJSON方法2.JSON.stringify()有过滤函数)

例6.

var person = {  age:4,  weight:"60kg",  toJSON:function(){    return {      height:"1.8m"    }  }};var personText = JSON.stringify(person,function(key,value){  switch(key){    case "height":      return value+" sss";    default:      return value;  };});console.log(personText);//{"height":"1.8m sss"}

顺序是:先调用对象自身的toJSON方法进行序列化2.如果有过滤函数的话,再使用步骤1返回的对象,通过过滤函数进行序列化

六.JSON.parse

var book = {  "title":"Professional JavaScript",  "authors":[    "Nicholas C. Zakas"  ],  edition:3,  year:2011,  releaseDate:new Date(2011,11,1)};var jsonText = JSON.stringify(book);var bookCopy = JSON.parse(jsonText,function(key,value){  if(key == "releaseDate"){    return new Date(value);  }else{    return value;  }});console.log(bookCopy);console.log(new Date());