JSON的序列化与反序列化及其在前后台交互中的应用

1、什么是JSON
  JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。

在JSON出现之前,大家一直用XML来传递数据。因为XML是一种纯文本格式,所以它适合在网络上交换数据。XML本身不算复杂,但是,加上DTD、XSD、XPath、XSLT等一大堆复杂的规范以后,任何正常的软件开发人员碰到XML都会感觉头大了,最后大家发现,即使你努力钻研几个月,也未必搞得清楚XML的规范。

终于,在2002年的一天,道格拉斯·克罗克福特(Douglas Crockford)同学为了拯救深陷水深火热同时又被某几个巨型软件企业长期愚弄的软件工程师,发明了JSON这种超轻量级的数据交换格式。

道格拉斯同学长期担任雅虎的高级架构师,自然钟情于JavaScript。他设计的JSON实际上是JavaScript的一个子集。在JSON中,一共就这么几种数据类型:

 - number:和JavaScript的number完全一致;<br>
 - boolean:就是JavaScript的true或false;
 - string:就是JavaScript的string;
 - null:就是JavaScript的null;
 - array:就是JavaScript的Array表示方式——[];
 - object:就是JavaScript的{...}表示方式。

以及上面的任意组合。

并且,JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。为了统一解析,JSON的字符串规定必须用双引号”“,Object的键也必须用双引号”“。

由于JSON非常简单,很快就风靡Web世界,并且成为ECMA标准。几乎所有编程语言都有解析JSON的库,而在JavaScript中,我们可以直接使用JSON,因为JavaScript内置了JSON的解析。

把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了。
2、JSON序列化
  让我们先把小明这个对象序列化成JSON格式的字符串:

var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};

JSON.stringify(xiaoming);
在chrome浏览器的console中运行上面代码,输出结果如下:

"{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}"

要输出得好看一些,可以加上参数,按缩进输出:

JSON.stringify(xiaoming, null, '  ');
"{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}"

第二个参数用于控制如何筛选对象的键值,如果我们只想输出指定的属性,可以传入Array:

JSON.stringify(xiaoming, ['name', 'skills'], '  ');
"{
  "name": "小明",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}"

还可以传入一个函数,这样对象的每个键值对都会被函数先处理:

function convert(key, value) {
    if (typeof value === 'string') {
        return value.toUpperCase();
    }
    return value;
}
JSON.stringify(xiaoming, convert, '  ');

结果:

"{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" MIDDLE SCHOOL",
  "skills": [
    "JAVASCRIPT",
    "JAVA",
    "PYTHON",
    "LISP"
  ]
}"

如果我们还想要精确控制如何序列化小明,可以给xiaoming定义一个toJSON()的方法,直接返回JSON应该序列化的数据:

var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
    toJSON: function () {
        return {             // 只输出name和age,并且改变了key:
            'Name': this.name,
            'Age': this.age
        };
    }
};
JSON.stringify(xiaoming);   // '{"Name":"小明","Age":14}'

3、JSON反序列化
拿到一个JSON格式的字符串,我们直接用JSON.parse()把它变成一个JavaScript对象:

JSON.parse('[1,2,3,true]');         // Array [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}');   // Object {name: '小明', age: 14}
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45

//还可以接收一个函数,用来转换解析出的属性:

JSON.parse('{"name":"小明","age":14}', function (key, value) {
    // 把number * 2:
    if (key === 'name') {
        return value + '同学';
    }
    return value;
});     // Object {name: '小明同学', age: 14}

4、JSON对象与JSON字符串
在数据传输流程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键。

JSON对象是直接可以使用JQuery操作的格式,和js中的对象一样,可以用对象(类名)点出属性(方法)。JSON字符串仅仅只是一个字符串,一个整体,不截取的话没办法取出其中存储的数据,不能直接使用,除非你只想alert()它。
JSON字符串:

var str1 = '{ "name": "haorooms", "sex": "man" }';

JSON对象:

var str2 = { "name": "haorooms", "sex": "man" };

读取JSON对象的属性值:

var str2 = { "name": "haorooms", "sex": "man" };
alert(str2.name);
//弹出” haorooms”
//对于复杂一点的JSON对象
var str={"GetUserPostByIdResult":{"Age":"33","ID":"2server","Name":"haorooms"}};
alert(str.GetUserPostByIdResult.Name); //弹出haorooms

对于JSON字符串,如果想像上面那样自如的读取其属性,必须运用下面的方法将JSON字符串领先转化为JSON对象(这一点在ajax返回的时候,经常遇到!):

var str = '{ "name": "haorooms", "sex": "man" }';
//方法1
var obj1 = eval('(' + str + ')');   //Object {name: "haorooms", sex: "man"}
//方法2
var obj2 = JSON.parse(str);     //Object {name: "haorooms", sex: "man"}

5、JSON实现后台与前端的交互
作为后台人员,与数据库交互、处理业务逻辑已经驾轻就熟,但与前端合作就显得不是那么熟练了。举一个例子,一个用户列表,我们从数据库取出来是一个List<User>,但它在前端显示就是一个很炫酷的用户列表,我们后台人员是需要把数据以表格样式呈现然后让前端人员去加样式呢,还是前端做好样式留出接口由后台人员给出数据呢?

刚刚接触网站开发可能都会出现类似的问题,我们是多希望前端和后台的工作分的清清楚楚啊!其实不用想那么复杂,JSON就可以帮我们!后台只需告诉前端,请求某一个URL地址就可以得到用户数据的JSON格式的数据,前端在需要的时候自己去请求就好,剩下的工作就由前端做就好了,清楚干净!
代码实例:

 /**
     * 测试获取所有用户列表 
     * @param request 
     * @return String 
     * @throws IOException  
     */  
    @RequestMapping("/getAllUserTest")  
    public String getAllUserTest(HttpServletRequest request, HttpServletResponse response) throws IOException {  
        //从数据库中取出所有用户信息,返回值为一个User对象集合,每个User对象包含username与age两个参数  
        List<User> findAll = userService.findAll();  
        //创建JSONArray实例  
        JSONArray jsonArray = new JSONArray();  
        //for each循环取出每个User对象  
        for(User user: findAll) {  
            //JSONObject是一个{}包裹起来的一个对象(Object),  
            //JSONArray则是[]包裹起来的一个数组(Array)  
            //此处为对象,所以用得到JSONObject  
             JSONObject jo = new JSONObject();  
             jo.put("username", user.getUsername());  
             jo.put("age", user.getAge());  
             jsonArray.add(jo);  
        }  
        try {  
             //后台输出测试  
             System.out.println(jsonArray.toString());  
             //设置字符集  
             response.setCharacterEncoding("UTF-8");  
             //页面输出  
             response.getWriter().println("JSON输出形式:");  
             response.getWriter().write(jsonArray.toString());  

         } catch (IOException e) {  
             e.printStackTrace();  
         }  
         return null;  
    }  

那么前端请求相应的URL就可以得到所有的用户信息了!效果如下:


20151206212911695.png

前台的数据如何通过JSON这种数据交换格式传入后台?

(1)将要传入后台的数据组装成JSON格式的字符串

var data = [{'name':'jim' , 'age':20} , {'name':'king' , 'age':26},{'name':'jge' , 'age':30}];
var jsonString = JSON.stringify(data);

(2)使用jQuery的ajax请求向后台传数据

$.ajax({
    type: "post",
    url: url,
    dataType : 'json',
    data : {'mydata':jsonString},
    success: function(data,textStatus){
        alert("操作成功");
    },
    error: function(xhr,status,errMsg){
        alert("操作失败!");
    }
});

(3)后台接收数据并解析

String jsonString = ServletActionContext.getRequest().getParameter("mydata");
JSONArray jsonArray = JSONArray.fromObject(jsonString);
for(int i = 0;i < jsonArray.length(); i++) {
    JSONObject jsonObj = jsonArray.getJSONObject(i);
    jsonObj.getInt("name");
    jsonObj.getString("age");
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容