【问题标题】:Typed AS3 JSON Encoder and Decoder?键入 AS3 JSON 编码器和解码器?
【发布时间】:2011-08-11 12:01:42
【问题描述】:

我需要以类型化的方式对 AS3 对象进行编码和解码。 http://code.google.com/p/as3corelib/ 仅支持无类型编码和解码。 http://code.google.com/p/ason/ 支持某种类型的对象,但不是很健壮,例如它在日期对象上失败。有什么建议吗?

明确一点:它必须是 JSON,并且必须是强类型和健壮的。

【问题讨论】:

  • @user293531: 男孩,你的 cmets 很活泼...
  • 如果你仍然需要这个,我可以更新以支持 Date's - 允许 Number's、String's 和 {time:Number} 类型(从 JSON 的角度)反序列化为 Date 对象。

标签: actionscript-3 json strong-typing typed


【解决方案1】:

JSON 并没有真正定义传达类型信息的方法。它只是字符串、整数和数组等等。所以基本上你需要某种基于 JSON 的基于的 AS3 “pickle”。我建议您研究一下 Flex/Flash 远程解决方案,看看它们如何打包要为 RPC 传输的对象;您也许可以修改该解决方案以使用 JSON。我实际上怀疑你会找到这样的图书馆。它必须是JSON吗?我很确定有基于 XML 的库可以做到这一点。

【讨论】:

  • code.google.com/p/ason 有这个“泡菜”或者你想怎么命名它。我不在乎是否将其他类型信息保存到 JSON。 XML 不是一个选项,因为发送的内容也需要由其他 JSON 编码器解码。
【解决方案2】:

JSON 没有在 Flash 虚拟机中实现,因此没有类型对象“JSON”,因为有“Xml”。所以基本上你可以很好地解码 JSON,但你要得到的类型是 Object。您可以使用对象中的键作为关联数组来访问数据。

http://blog.alien109.com/2009/02/11/php5-json-as3corelib-a-beautiful-thing/

来自 adobe 的 JSON lib/utils 官方: http://code.google.com/p/as3corelib/source/browse/#svn%2Ftrunk%2Fsrc%2Fcom%2Fadobe%2Fserialization%2Fjson

尽善尽美。 :)

【讨论】:

  • 我已经提到了 AS3CoreLib,并说它没有用。我已经指出了 ASON Lib,它有一些类型的支持,但不够健壮。
  • 啊,我的错!有时我会略过问题:O
【解决方案3】:

Flash 有自己的序列化系统。

var serializer:ByteArray = new ByteArray();
serializer.writeObject(new Sprite());
serializer.position = 0;
var data:String = serializer.readUTFBytes(serializer.bytesAvailable);
trace(data); //Will show you the binary jibberish

您可以使用registerClassAlias 添加对自定义类的支持。

【讨论】:

  • 我不想要你展示的 AMF,而是我的问题中写的 JSON。
【解决方案4】:

JSON 是内置在 AS3 中的。通过网络传输数据的首选方法是 AMF,它确实为您提供了类型化的对象。

如果您必须使用 JSON,那么我猜您可能需要使用某种 自定义协议 才能对类型进行编码/解码。

您实际上需要一个反射实用程序来读取 JSON 格式的 bean,然后生成您的对象。这真的取决于你想走多深。

as3Commons 有一个可以提供帮助的反射包。他们还有一个 JSONTypeProvider,它不是您所需要的,但可以让您找到正确的方向。

您可以修改任何 IOC 框架以通过解析 JSON 而不是大多数人使用的常规 XML 来生成上下文。

您可以修改 ASON 并添加自定义类型解析器。您必须在 JSON 对象中发送一个包含对象类型的变量。并将其与flash.utils.getDefinitionByName 一起使用。

另一种方法是仅使用常规 JSON 解析器解析对象,然后如果它具有已定义的类型,则创建该对象的实例,并初始化属性。

这样的东西,让你开始:

var beanInfo:Object = JSON.decode( jsonString );
beanInfo = _parseBean( beanInfo );

private function _parseBean(beanInfo:Object):Object{
    if ( beanInfo.hasOwnProperty("_type") ) {
        var clazz:Class = getDefinitionByName( beanInfo._type ) as Class;
        beanInfo.__clazz = clazz;
        var instance:Object = new clazz;
        for( var prop:String in beanInfo ) {
            if( instance.hasOwnProperty(prop) ) target[prop] = _getPropertyFrom(beanInfo[prop]);
        }
    }
}

private function _getPropertyFrom(property:String):* {
    var xml:XML = describeType( beanInfo.__clazz );
    //find the type of the current property.
    var type:String = xml...
    //if is a simple object then do something like
    switch( type ) {
        case "number":
            return parseFloat(property ) as Number;
        break;
        case "int":
        case "uint":
            return parseInt( property );
        break;
        case "string":
            return property as String;
        break;
        ...
        default
            //As it is it does not suppor complex objects.
           //You would use reflection. But then you could save the whole switch...

        break;

    }


}

【讨论】:

    【解决方案5】:

    我现在已经 fork http://code.google.com/p/as3corelib/ 的 json 部分并添加了类型化对象支持...

    【讨论】:

    • 你的分叉 as3corelib 在任何地方都可用吗?
    【解决方案6】:

    您需要考虑两个操作:1) 将特定类型的对象序列化为 JSON;2) 将 JSON 字符串反序列化为特定类型的对象。

    序列化部分很简单——只需使用内置的 JSON.stringify()。在 ActionScript 中将 JSON 字符串反序列化为特定类型的对象是有趣的地方(以及您问题的答案所在)。您需要为需要反序列化的类编写自己的反序列化函数。在该函数中,您需要向 JSON.parse() 提供一个 reviver 函数,它允许您自定义 JSON 的反序列化方式。

    例如:

        public static function deserializeComplexObject(json:String):ComplexObject
        {
            if (null == json || "null" == json)
            {
                return null;
            }
            var complexObject:ComplexObject = new ComplexObject();
            var parsedObject:Object = JSON.parse(
                json,
                function (key:String, value:Object):*
                {
                    switch (key)
                    {
                        case “keyForNumber”:
                            return value;
                        case “keyForComplexObject2”:
                            return deserializeComplexObject2(JSON.stringify(value));
                        case “keyForComplexObject3”:
                            return deserializeComplexObject3(JSON.stringify(value));
                        case “keyForString”:
                            return value;
                        case “keyForBoolean”:
                            return value;
                        default:
                            return value;
                    }
                }
            );
            complexObject.keyForNumber = parsedObject.keyForNumber;
            complexObject.keyForComplexObject2 = parsedObject.keyForComplexObject2;
            // continue setting fields
            // …
            return complexObject;
        }
    

    每个 case 语句对应于 JSON 字符串中的顶级键。您实际上不需要为每个键单独的 case 语句 - 您可以使用默认 case 来处理映射到简单类型之一的值(对象、数组、字符串、数字、布尔值、null)的所有键,方法是返回价值原样。

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 2020-12-02
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多