类型 AS3 JSON 编码器和解码器?

发布于 2024-11-02 21:12:55 字数 310 浏览 6 评论 0原文

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

明确地说:它必须是 JSON,并且必须是强类型且健壮的。

I need to encode and Decode AS3 Objects in a typed manner. http://code.google.com/p/as3corelib/ only supports untyped encoding and decoding.
http://code.google.com/p/ason/ supports some kind of typed objects but is not very robust, e.g. it fails on Date Objects. Any Recommendations ?

To make it clear: It MUST be JSON and it MUST be strong typed and robust.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

绳情 2024-11-09 21:12:55

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;

    }


}

JSON is built in in AS3. The preferred method to transmit data over the wire is AMF, which does provide you typed objects.

If you have to use JSON, then I guess that you might have to do with some sort of custom protocol to be able encode/decode with types.

You would actually need a reflection utility that read beans in JSON format and then produce your object. It really depends on how deep you want to go.

as3Commons has a reflect package that could help. They also have a JSONTypeProvider, which is not exactly what you need but can put you in the right tract.

You could modify any of the IOC frameworks to produce the context by parsing JSON instead of the regular XML most of them use.

You could modify ASON and add a custom type parser. You would have to send a variable in your JSON object containing the type of the object. And use that in with flash.utils.getDefinitionByName.

Another approach would be to just parse the objects with a regular JSON parser and then if it has a defined type create an instance of that objet, and initialize the properties.

Something like this, to get you started:

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;

    }


}
我很OK 2024-11-09 21:12:55

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< /a> 添加对自定义类的支持。

Flash has its own serialization system.

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

You can use registerClassAlias to add support for custom classes.

小姐丶请自重 2024-11-09 21:12:55

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

JSON doens't really define a means to convey type information. It's just strings and ints and arrays and so on. So basically you need some sort of "pickle" for AS3 that's based on JSON. I would suggest you look into Flex/Flash remoting solutions and see how they package objects to be transmitted for RPC; you might be able to modify that solution to use JSON. I'm actually doubtful you'll find a library like this. Does it have to be JSON? I'm pretty sure there are XML based libraries that do this.

你的往事 2024-11-09 21:12:55

JSON 未在闪存虚拟机中实现,因此不存在类型化对象“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/svn%2Ftrunk%2Fsrc%2Fcom%2Fadobe%2Fserialization%2Fjson" google.com/p/as3corelib/source/browse/#svn%2Ftrunk%2Fsrc%2Fcom%2Fadobe%2Fserialization%2Fjson

尽善尽美。 :)

JSON is not implemented in the flash virtual machine, and therefore there is no typed object "JSON" as there is "Xml." So basically you can decode JSON just fine, but the type you're going to get is Object. You can them access data using the key in the object as an associative array.

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

JSON lib/utils official from adobe:
http://code.google.com/p/as3corelib/source/browse/#svn%2Ftrunk%2Fsrc%2Fcom%2Fadobe%2Fserialization%2Fjson

As good as it gets. :)

勿挽旧人 2024-11-09 21:12:55

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

序列化部分很简单 - 只需使用内置的 JSON.stringify() 即可。在 ActionScript 中将 JSON 字符串反序列化为特定类型的对象是有趣的地方(也是您问题的答案所在)。您需要为需要反序列化的类编写自己的反序列化函数。在该函数中,您需要为 JSON.parse(),它允许您自定义 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 语句 - 您可以使用默认情况来处理映射到简单类型之一(对象、数组、字符串、数字、布尔值、null)的值的所有键,方法是返回按原样值。

There are two operations you need to consider: 1) serializing an object of a particular type into JSON and 2) deserializing a JSON string into an object of a particular type.

The serialization part is easy - just use the built-in JSON.stringify(). Deserializing a JSON string into an object of a particular type in ActionScript is where it gets interesting (and where the answer to your question is). You need to write your own deserialization function for the classe(s) you will need to deserialize. In that function, you need to provide a reviver function to JSON.parse(), which allows you to customize how the JSON gets deserialized.

For example:

    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;
    }

Each case statement corresponds to a top-level key in the JSON string. You don't actually need separate case statements for every key - you can use the default case to handle all keys that map to values that are one of the simple types (Object, Array, String, Number, Boolean, null) by returning the value as-is.

醉生梦死 2024-11-09 21:12:55

I have now forked the json part of http://code.google.com/p/as3corelib/ and added typed object support...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文