我需要将对象的状态保存到文件中并稍后检索它。我发现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 = "Vaidhehi";
}
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;
}
}
答案 0 :(得分:2)
使用JSON-GLib进行序列化是包含复杂类型的属性的递归。
如果GObject的属性包含另一个GObject,json_gobject_serialize()
将递归调用存储在属性中的实例上的json_gobject_serialize()
- 或者如果属性未设置则序列化null
。
答案 1 :(得分:1)
我已经实现了一个对象来支持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);
}
}