什么是SON格式?
XML虽然强大但有人觉得xml不够简洁,编码和解码也有一定难度,于是21世纪初有人发明了JSON编码,相比xml内容少并且容易阅读,编码解码的难度也比xml简单,因此迅速得到普及成为比xml更加受欢迎的编码格式。JSON编码来源于对数据结构的分析,所有数据结构都可以分为3种基本数据组成单位:
第一种类型是标量,也就是一个单独的字符串或数字。
第二种类型是序列,也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组或列表
第三种类型是映射,也就是一个名/值对,又称作关联数组(Object或字典(Dictionary)
几乎所有语言都有这三种类型,as3也不例外,这是JSON成为通用的编码格式基础,JSON提出如下规范:
1.并列的数据之间用逗号(",")分隔。
2.映射用冒号(":")表示。
3.并列数据的集合(数组)用方括号("[]")表示。
4.映射的集合(对象)用大括号("{}")表示。
这符合像c++,java,c#,javascript等常用语言的编写习惯,as3也不例外,例如:
[
{"姓名":"张三","性别":"男","年纪":28},
{"姓名":"四凤","性别":女,"年纪":24}
]
这个结构和as3的字面值非常相似,因此使用as3编写JSON有非常大的优势,目前as3中还没有内置JSON编码,需要下载Adobe的JSON工具包,下载完后就可以使用JSON类编码和解码,JSON使用起来也非常简单,它仅包括两个静态方法:JSON.encode(o:Object):String和JSON.decode( s:String, strict:Boolean = true ):*,endode()可以将关联数组、Array转化为字符串,decode()可以将json格式的字符串转化为Object,strict用于严格检查,如果格式不标准会报JSONParseError的错误,下面是使用JSON编码和解码的例子:
- var infoJSON:String = '{"newinfo": [{ "news1": "never1", "news2": "never", "news3": "never3" },{ "news1": "never4", "news2": "never5", "news3": "never6" }]}';
- var jsonObject:Object=JSON.decode(infoJSON);
- trace(jsonObject["newinfo"][1]["news1"]);
- var uploadObject:Object={"grade":[1,2,3,4,5],"money":[100,300,500,700,1000]};
- trace(JSON.encode(uploadObject));
- var uploadArray:Array=[{"grade":1},{"money":100}];
- trace(JSON.encode(uploadArray));
复制代码
为了方便使用JSON格式与服务器通信,我们也编写一个加载器JSONLoader,如下:
- JSONLoader.as<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
- package xin.loaders
- {
- import com.adobe.serialization.json.JSON;
- import flash.events.Event;
- import flash.events.IOErrorEvent;
- import flash.events.SecurityErrorEvent;
- import flash.net.URLLoader;
- import flash.net.URLRequest;
- import flash.net.URLRequestMethod;
- import flash.net.URLVariables;
- import flash.utils.Dictionary;
- /**
- * JSONLoader加载器,这个类是个工具类,可以同时加载多个xml数据 ,在JSONLoader内部使用奴隶与死囚优化法则来减小内存消耗。
- * @author qiuxin
- *
- */
- public class JSONLoader extends URLLoader
- {
- private static var limbo:Dictionary=new Dictionary(true);
-
- private var loadding:Boolean;
- private var competeHandle:Function;
-
-
- public static function load(url:String, competeHandle:Function, variables:URLVariables=null, method:String="GET"):void
- {
- var request:URLRequest;
- var loader:JSONLoader
-
- //在缓存寻找非运作的loader
- for(var criminal:Object in limbo)
- {
- if(!JSONLoader(criminal).loadding)
- {
- loader=criminal as JSONLoader;
- request=limbo[loader] as URLRequest;
- request.url=url;
- break;
- }
- }
- //未找到则重新创建
- if (!loader)
- {
- request=new URLRequest(url);
- loader=new JSONLoader(request);
- limbo[loader]=request;
- }
- request.data=variables;
- request.method=method;
- loader.competeHandle=competeHandle;
- loader.load(request);
- loader.loadding=true;
- }
-
-
- public function JSONLoader(request:URLRequest=null)
- {
- super(request);
-
- addEventListener(Event.COMPLETE, xmlLoadComplete);
- addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandle);
- addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandle);
- }
-
-
- private function ioErrorHandle(event:IOErrorEvent):void
- {
- trace("加载xml时服务器未能返回");
- }
-
-
- private function securityErrorHandle(event:SecurityErrorEvent):void
- {
- trace("加载xml时发生安全沙箱错误");
- }
-
-
- private function xmlLoadComplete(event:Event):void
- {
- loadding=false;
- var result:Object=JSON.decode(event.target.data);
- competeHandle(result);
- }
- }
- }
复制代码
有了JSONLoader后在任何地方可以通过静态方法load()加载后台数据,加载完后自动调用每个数据的回调函数并且传入加载的xml。JSONLoader可以同时加载多个数据,由于JSONLoader在内部使用了内存优化(奴隶与死囚优化法则),频繁加载也不会带来内存溢出问题。
测试代码如下:
这里提供Adobe的JSON包和我写的JSON类:
json包:
json.rar (16.96 KB)
JSONLoader:
xin.rar (1.15 KB)