【问题标题】:vala: Serializing object property with Json.gobject_serialize?vala:使用 Json.gobject_serialize 序列化对象属性?
【发布时间】:2017-09-06 17:28:15
【问题描述】:

我需要将对象的状态保存到文件中并稍后检索它。我发现 JSON 序列化会有所帮助,并找到了这个方法 Json.gobject_serialize。使用这种方法,我可以成功地序列化包含字符串属性的对象。但是,如果对象 A 由其中的另一个对象(例如 B)组成并且我需要序列化对象 A,我该怎么办。

编辑

如果对象 A 由对象数组(比如 B)组成,我该怎么办? 为此,我创建了一个小型测试程序,但在那次尝试中失败了。我找不到任何关于 vala 的 JSON 序列化的详细文档。

public class Foo : Object {

    public int iFoo {get; set;}
    public string sFoo {get; set;}

    Bar[] _bar = {};
    public Bar[] bar {get {return _bar;} set{_bar = value;}}

    public class Bar : Object {
        public int iBar {get; set;}
        public string sBar {get; set;}

        construct {
            iBar = 02;
            sBar = "OutOfRange";
        }
    }

    construct {
        _bar += new Bar();

        iFoo = 74;
        sFoo = "GIrafee";
    }

    public static int main () {
        Json.Node root = Json.gobject_serialize (new Foo());

        Json.Generator generator = new Json.Generator ();
        generator.set_root (root);
        stdout.printf(generator.to_data (null) + "\n");

        return 0;
    }
}

【问题讨论】:

    标签: json vala gobject


    【解决方案1】:

    使用 JSON-GLib 进行序列化对于包含复杂类型的属性是递归的。

    如果 GObject 的属性包含另一个 GObject,json_gobject_serialize() 将递归调用存储在该属性内的实例上的 json_gobject_serialize() — 如果未设置该属性,则序列化 null

    【讨论】:

    • 如果我有一个对象数组或任何基本类型的数组我该怎么办
    • Vala 复合/泛型类型在 GObject 中没有映射;您需要通过实现 JsonSerializable 接口来实现自己的序列化。
    • 这里是一个 SList 序列化的例子:github.com/major-lab/json-api-glib/blob/master/src/…
    【解决方案2】:

    我已经实现了一个对象来支持 Json.Serializable 接口,如下所示:

        public class DbObject : GLib.Object, Json.Serializable
        {
            public Json.Object? meta { get; construct set; default = null; }
            public VersionSync version { get; set; default = VersionSync.UNKNOWN; }
    
            public virtual Value get_property (ParamSpec pspec)
            {
                Value prop_value = GLib.Value(pspec.value_type);
                (this as GLib.Object).get_property(pspec.name, ref prop_value);
                stdout.printf ("%s --> %s\n", prop_value.type_name(), prop_value.strdup_contents());
    
                return prop_value;
            }
    
            public virtual void set_property (ParamSpec pspec, Value value)
            {
                (this as GLib.Object).set_property (pspec.name, value);
            }
    
            public unowned ParamSpec? find_property (string name)
            {
                return ((ObjectClass) get_type ().class_ref ()).find_property (name);
            }
    
            public virtual Json.Node serialize_property (string property_name, Value @value, ParamSpec pspec)
            {
                if (@value.type ().is_a (typeof (Json.Object)))
                {
                    var obj = @value as Json.Object;
                    if (obj != null)
                    {
                        var node = new Json.Node (NodeType.OBJECT);
                        node.set_object (obj);
                        return node;
                    }
                }
                else if (@value.type ().is_a (typeof (Gee.ArrayList)))
                {
                    unowned Gee.ArrayList<GLib.Object> list_value = @value as Gee.ArrayList<GLib.Object>;
                    if (list_value != null || property_name == "data")
                    {
                        var array = new Json.Array.sized (list_value.size);
                        foreach (var item in list_value)
                        {
                            array.add_element (gobject_serialize (item));
                        }
    
                        var node = new Json.Node (NodeType.ARRAY);
                        node.set_array (array);
                        return node;
                    }
                }
                else if (@value.type ().is_a (typeof (GLib.Array)))
                {
                    unowned GLib.Array<GLib.Object> array_value = @value as GLib.Array<GLib.Object>;
                    if (array_value != null || property_name == "data")
                    {
                        var array = new Json.Array.sized (array_value.length);
                        for (int i = 0; i < array_value.length; i++) {
                            array.add_element (gobject_serialize (array_value.index(i)));
                        }
    
                        var node = new Json.Node (NodeType.ARRAY);
                        node.set_array (array);
                        return node;
                    }
                }            
                else if (@value.type ().is_a (typeof (HashTable)))
                {
                    var obj = new Json.Object ();
                    var ht_string = @value as HashTable<string, string>;
                    if (ht_string != null)
                    {
                        ht_string.foreach ((k, v) => {
                            obj.set_string_member (k, v);
                        });
    
                        var node = new Json.Node (NodeType.OBJECT);
                        node.set_object (obj);
                        return node;
                    } else {
                        var ht_object = @value as HashTable<string, GLib.Object>;
                        if (ht_object != null)
                        {
                            ht_object.foreach ((k, v) => {
                                obj.set_member (k, gobject_serialize (v));
                            });    
    
                            var node = new Json.Node (NodeType.OBJECT);
                            node.set_object (obj);
                            return node;
                        }
                    }
                }
    
                return default_serialize_property (property_name, @value, pspec);
            }
    
            public virtual bool deserialize_property (string property_name, out Value @value, ParamSpec pspec, Json.Node property_node)
            {
                return default_deserialize_property (property_name, out @value, pspec, property_node);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 2021-08-28
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多