Typed AS3 JSON Encoder and Decoder?

[亡魂溺海] 提交于 2019-12-31 02:09:25

问题


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.


回答1:


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;

    }


}



回答2:


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.




回答3:


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.




回答4:


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. :)




回答5:


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.




回答6:


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



来源:https://stackoverflow.com/questions/5764646/typed-as3-json-encoder-and-decoder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!