You'll have to create a ZooDeserializer:
Zoo.java
import com.google.gson.*;
import java.lang.reflect.*;
import java.util.*;
public class Zoo {
private Animal tiger;
private Animal lion;
@Override
public String toString() {
return "Come see our triumphant tiger (" + tiger.toString()
+ ") and our laudable lion (" + lion.toString() + ") at the zoo!";
}
interface Animal {
}
static class Tiger implements Animal {
@Override
public String toString() {
return "with striking stripes";
}
}
static class Lion implements Animal {
@Override
public String toString() {
return "with a marvelous mane";
}
}
static class ZooDeserializer implements JsonDeserializer<Zoo> {
private static Map<String, Class<? extends Animal>> animals =
new HashMap();
static {
for (Class<? extends Animal> c: Arrays.asList(
// List each Animal implementer that you want to be
// able to deserialize here
Tiger.class,
Lion.class)) {
animals.put(c.getSimpleName().toLowerCase(), c);
}
}
/**
* Build a Zoo from json. This method will return null if:
* 1. json is not a JsonObject
* 2. a key in json is not a field in Zoo
* 3. a key in json does not correspond to a class in the animals map
* 4. a value in json cannot be properly deserialized into the named
* Animal class
*/
public Zoo deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
Zoo zoo = new Zoo();
try {
for (Map.Entry<String, JsonElement> kv:
json.getAsJsonObject().entrySet()) {
String name = kv.getKey();
Field f = Zoo.class.getDeclaredField(name);
f.setAccessible(true);
Animal a = context.deserialize(kv.getValue(),
animals.get(name));
f.set(zoo, a);
}
return zoo;
} catch (Exception e) {
return null;
}
}
}
public static void main(String[] args) {
String json = "{tiger:{},lion:{}}";
Gson gson = new GsonBuilder()
.registerTypeAdapter(Zoo.class, new ZooDeserializer())
.create();
Zoo zoo = gson.fromJson(json, Zoo.class);
System.out.println(zoo);
}
}
$ java -cp .:gson-2.1.jar Zoo
Come see our triumphant tiger (with striking stripes) and our laudable
lion (with a marvelous mane) at the zoo!
I wrote this deserializer in a somewhat generic way that would allow
to add a single instance of various different animals to your zoo:
each Animal type must be added to the ZooDeserializer static block.
With minor modifications, you could have a Zoo2 class with a list of
animals:
Zoo2.java
import com.google.gson.*;
import java.lang.reflect.*;
import java.util.*;
public class Zoo2 {
private final List<Animal> animals;
public Zoo2(List<Animal> animals) {
this.animals = animals;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Come see our many
animals at the zoo:");
for (Animal a: animals) {
sb.append('\n').append(a);
}
return sb.toString();
}
interface Animal {
}
static class Tiger implements Animal {
@Override
public String toString() {
return "a triumphant tiger with striking stripes";
}
}
static class Lion implements Animal {
@Override
public String toString() {
return "a laudable lion with a marvelous mane";
}
}
static class ZooDeserializer implements JsonDeserializer<Zoo2> {
private static Map<String, Class<? extends Animal>>
animalClasses = new HashMap();
static {
for (Class<? extends Animal> c: Arrays.asList(
// List each Animal implementer that you want to be
// able to deserialize here
Tiger.class,
Lion.class)) {
animalClasses.put(c.getSimpleName().toLowerCase(), c);
}
}
/**
* Build a Zoo2 from json. The json must be of the form:
*
* { animalType: {},
* anotherType: [{}, {}],
* ... }
*
* The animalType must correspond to the lowercase version of a class
* registered in the static initialization block of this deserializer.
* The value corresponding to that key must be a single JsonObject
* representing an instance of the named class, or a list of such
* JsonObjects.
*
* @throws JsonParseException if the json does not represent a proper
* zoo object.
*/
public Zoo2 deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
List<Animal> animals = new ArrayList();
for (Map.Entry<String, JsonElement> kv:
json.getAsJsonObject().entrySet()) {
Class animalClass = animalClasses.get(kv.getKey());
JsonElement obj = kv.getValue();
if (obj.isJsonArray()) {
for (JsonElement j: obj.getAsJsonArray()) {
animals.add((Animal) context.deserialize(j,
animalClass));
}
} else {
animals.add((Animal) context.deserialize(obj, animalClass));
}
}
return new Zoo2(animals);
}
}
public static void main(String[] args) {
String json = "{tiger:{},lion:[{},{}]}";
Gson gson = new GsonBuilder()
.registerTypeAdapter(Zoo2.class, new ZooDeserializer())
.create();
Zoo2 zoo = gson.fromJson(json, Zoo2.class);
System.out.println(zoo);
}
}
$ java -cp .:gson-2.1.jar Zoo2
Come see our many animals at the zoo:
a triumphant tiger with striking stripes
a laudable lion with a marvelous mane
a laudable lion with a marvelous mane
> --
> You received this message because you are subscribed to the Google Groups "google-gson" group.
> To post to this group, send email to
googl...@googlegroups.com.
> To unsubscribe from this group, send email to
google-gson...@googlegroups.com.
> For more options, visit this group at
http://groups.google.com/group/google-gson?hl=en.
>