AiorosXu / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

Dynamic serialization and deserialization via class interface #400

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I have created a patch against gson-2.1 that adds code for allowing classes to 
define serialization and deserialization by implementing a simple interface. 
The benefit of this approach is that there is no longer a need to register 
special handlers for each class that requires custom serialization. It can be 
used as follows:

public class Foo implements JsonSerialization, 
JsonDeserializedBy<FooDeserializer> {
    public String name;
    public JsonElement serialize (JsonSerializationContext jsc) {
        return new JsonPrimitive(name);
    }
}

public class FooDeserializer implements JsonDeserializer<Foo> {
    public Foo deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) {
        Foo f = new Foo();
        f.name = je.getAsString();
        return f;
    }
}

...
Foo foo = new Foo();
foo.name = "foo";
gson.toJson(foo); // "foo"
gson.fromJson(gson.toJson(foo), Foo.class).name; // "foo"

With my patch, a Gson object now checks the argument sent to toJson to 
determine if it implements JsonSerialization. If so, it calls its 
serialize(jsc) method to retrieve a JsonElement for that class.

When fromJson is called, the given class is inspected to determine if it 
implements the JsonDeserializer interface. If so, the class specified in the 
template parameter (in this case FooDeserializer) is used for deserialization 
by creating a new instance of that class (using the no-argument constructor), 
and then deserialize is called as with any JsonDeserializer object.

This patch adds the two new interfaces (JsonSerialization and 
JsonDeserialization) and adds a few lines of code to Gson in order to provide 
the aforementioned functionality. I'm not sure I chose the appropriate location 
to insert the functionality, and the code is pretty ugly, but it seems to work 
pretty well in my limited test cases.

I'll license the patch under the same license as gson, in case anyone is 
concerned about that.

Original issue reported on code.google.com by mint...@everlaw.com on 12 Jan 2012 at 1:59

Attachments:

GoogleCodeExporter commented 9 years ago
Sorry, the example code has a small mistake, as I renamed one of the interfaces 
before submitting the patch. Where it says "JsonDeserializedBy", it should say 
"JsonDeserialization". The patch and the rest of my post are accurate.

Original comment by mint...@everlaw.com on 12 Jan 2012 at 2:03

GoogleCodeExporter commented 9 years ago
That's extremely clever!

FYI, if you're willing to make a single call to 
GsonBuilder.registerTypeAdapterFactory(), I don't think you need to make any 
changes to Gson 2.1 to make this work.

Original comment by jessewil...@google.com on 12 Jan 2012 at 6:03

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Will that actually work, though? From what I could tell looking at the code, a 
TypeAdaptor is registered against a specific type that is later retrieved with 
a map lookup. Since my method relies on any object simply implementing an 
interface, doesn't that require a change to Gson?

The alternative would be for each object to register itself with some 
globally-used Gson object. I preferred the interface approach.

Original comment by mint...@everlaw.com on 18 Jan 2012 at 7:06