Codemwnci
Codemwnci

Reputation: 54884

JSON Polymorphism

I have a List of javascript objects on my client side, which are a list of "events" that a user has executed. When the user is ready, I want to send this to the server. The order of events is important, so preserving the list order is necessary.

What I would like to do is to have a JSON library (don't mind which one) to bind the JSON to some Event objects in my Java code, where Event is an abstract class, and I have 3 concrete classes that all extend Event (lets say EventA, EventB and EventC).

Ideal scenario would be something like

List<Event> events = jsonlibrary.deserialise(jsonString);

which may contain a list of items such as

[eventA, eventC, eventA, eventA, eventB]

Is this possible, or do I have to inspect the JSON tree manually, and deserialise the individual elements of the json array?

Upvotes: 6

Views: 2941

Answers (4)

user1988452
user1988452

Reputation: 11

I began a library that implements the desired fonctionality (for json and xml) if the json is encoded by the same library :

https://github.com/giraudsa/serialisation

to use it, MyObject myObject = new SpecialisedObject();

String json = JsonMarshaller.ToJson(myObject);
MyObject myClonedObject = JsonUnMarshaller(json);

Upvotes: 0

BendaThierry.com
BendaThierry.com

Reputation: 2109

Why not using jackson json library ?

It is a full Object/JSON Mapper with data binding functionnality.

It is fast, small footprint, documented, overused, and many others things you will enjoy!

Upvotes: 1

eugen
eugen

Reputation: 5916

You could use Genson library http://code.google.com/p/genson/. It can deserialize to concrete types if the json was produced using Genson. Otherwise you only need to add something like [{"@class":"my.java.class", "the rest of the properties"}...]

// an example
abstract class Event {
 String id;
}

class Click extends Event {
 double x, y;
}

// you can define aliases instead of plain class name with package (its a bit nicer and more secure)
Genson genson = new Genson.Builder().setWithClassMetadata(true).addAlias("click",
            Click.class).create();
String json = "[{\"@class\":\"click\", \"id\":\"here\", \"x\":1,\"y\":2}]";

// deserialize to an unknown type with a cast warning
List<Event> events =  genson.deserialize(json, List.class);

// or better define to which generic type
GenericType<List<Event>> eventListType = new GenericType<List<Event>>() {};
events = genson.deserialize(json, eventListType);

EDIT here is the wiki example http://code.google.com/p/genson/wiki/GettingStarted#Interface/Abstract_classes_support

Upvotes: 1

Philipp
Philipp

Reputation: 69663

JSON objects are just key/value pairs and contain no type information. That means identifying the type of a JSON object automatically isn't possible. You have to implement some logic on the server-side to find out what kind of event you are dealing with.

I would suggest to use a factory method which takes a json string, parses it to find out what kind of Event it is, builds an Event object of the correct subclass and returns it.

Upvotes: 6

Related Questions