Skip to content

Commit

Permalink
gson advanced list examples
Browse files Browse the repository at this point in the history
  • Loading branch information
rockoder committed Mar 4, 2019
1 parent 00c1152 commit c2cb4d4
Show file tree
Hide file tree
Showing 7 changed files with 489 additions and 0 deletions.
5 changes: 5 additions & 0 deletions gson/src/main/java/org/baeldung/gson/entities/Animal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.baeldung.gson.entities;

public abstract class Animal {
public String type = "Animal";
}
19 changes: 19 additions & 0 deletions gson/src/main/java/org/baeldung/gson/entities/Cow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.baeldung.gson.entities;

public class Cow extends Animal {
private String breed;

public Cow() {
breed = "Jersey";
type = "Cow";
}

public String getBreed() {
return breed;
}

public void setBreed(String breed) {
this.breed = breed;
}
}

18 changes: 18 additions & 0 deletions gson/src/main/java/org/baeldung/gson/entities/Dog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.baeldung.gson.entities;

public class Dog extends Animal {
private String petName;

public Dog() {
petName = "Milo";
type = "Dog";
}

public String getPetName() {
return petName;
}

public void setPetName(String petName) {
this.petName = petName;
}
}
37 changes: 37 additions & 0 deletions gson/src/main/java/org/baeldung/gson/entities/MyClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.baeldung.gson.entities;

public class MyClass {
private int id;
private String[] strings;

public MyClass() {
id = 1;
strings = new String[] { "a", "b" };
}


// @Override
// public String toString() {
// return "{" +
// "id=" + id +
// ", name='" + name + '\'' +
// ", strings=" + Arrays.toString(strings) +
// '}';
// }

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String[] getStrings() {
return strings;
}

public void setStrings(String[] strings) {
this.strings = strings;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.baeldung.gson.serialization;

import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import org.baeldung.gson.entities.Animal;

public class AnimalDeserializer implements JsonDeserializer<Animal> {
private String animalTypeElementName;
private Gson gson;
private Map<String, Class<? extends Animal>> animalTypeRegistry;

public AnimalDeserializer(String animalTypeElementName) {
this.animalTypeElementName = animalTypeElementName;
this.gson = new Gson();
this.animalTypeRegistry = new HashMap<>();
}

public void registerBarnType(String animalTypeName, Class<? extends Animal> animalType) {
animalTypeRegistry.put(animalTypeName, animalType);
}

public Animal deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
JsonObject animalObject = json.getAsJsonObject();
JsonElement animalTypeElement = animalObject.get(animalTypeElementName);

Class<? extends Animal> animalType = animalTypeRegistry.get(animalTypeElement.getAsString());
return gson.fromJson(animalObject, animalType);
}
}
110 changes: 110 additions & 0 deletions gson/src/test/java/org/baeldung/gson/advance/GsonAdvanceUnitTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package org.baeldung.gson.advance;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import org.baeldung.gson.entities.Animal;
import org.baeldung.gson.entities.Cow;
import org.baeldung.gson.entities.Dog;
import org.baeldung.gson.entities.MyClass;
import org.baeldung.gson.serialization.AnimalDeserializer;
import org.junit.Test;

public class GsonAdvanceUnitTest {

@Test public void givenListOfMyClass_whenSerializing_thenCorrect() {
List<MyClass> list = new ArrayList<>();
list.add(new MyClass());
list.add(new MyClass());

Gson gson = new Gson();
String jsonString = gson.toJson(list);
String expectedString = "[{\"id\":1,\"strings\":[\"a\",\"b\"]},{\"id\":1,\"strings\":[\"a\",\"b\"]}]";

assertEquals(expectedString, jsonString);
}

@Test(expected = ClassCastException.class)
public void givenJsonString_whenIncorrectDeserializing_thenThrowClassCastException() {
String inputString = "[{\"id\":1,\"strings\":[\"a\",\"b\"]},{\"id\":1,\"strings\":[\"a\",\"b\"]}]";

Gson gson = new Gson();
List<MyClass> list = gson.fromJson(inputString, ArrayList.class);

assertEquals(2, list.size());
int id = list.get(0).getId();
}

@Test public void givenJsonString_whenDeserializing_thenReturnListOfMyClass() {
String inputString = "[{\"id\":1,\"strings\":[\"a\",\"b\"]},{\"id\":1,\"strings\":[\"a\",\"b\"]}]";
Type listOfMyClassObject = new TypeToken<ArrayList<MyClass>>() {}.getType();

Gson gson = new Gson();
List<MyClass> list = gson.fromJson(inputString, listOfMyClassObject);

assertEquals(2, list.size());
assertEquals(1, list.get(0).getId());
}

@Test public void givenPolymorphicList_whenSerializeWithTypeAdapter_thenCorrect() {
String expectedString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";

List<Animal> inList = new ArrayList<>();
inList.add(new Dog());
inList.add(new Cow());

String jsonString = new Gson().toJson(inList);

assertEquals(expectedString, jsonString);
}

@Test public void givenPolymorphicList_whenDeserializeWithTypeAdapter_thenCorrect() {
String inputString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";

AnimalDeserializer deserializer = new AnimalDeserializer("type");
deserializer.registerBarnType("Dog", Dog.class);
deserializer.registerBarnType("Cow", Cow.class);
Gson gson = new GsonBuilder()
.registerTypeAdapter(Animal.class, deserializer)
.create();

List<Animal> outList = gson.fromJson(inputString, new TypeToken<List<Animal>>(){}.getType());

assertEquals(2, outList.size());
assertTrue(outList.get(0) instanceof Dog);
}

@Test public void givenPolymorphicList_whenSerializeWithRuntimeTypeAdapter_thenCorrect() {
String expectedString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";

List<Animal> inList = new ArrayList<>();
inList.add(new Dog());
inList.add(new Cow());
String jsonString = new Gson().toJson(inList);

assertEquals(expectedString, jsonString);
}

@Test public void givenPolymorphicList_whenDeserializeWithRuntimeTypeAdapter_thenCorrect() {
String inputString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";

Type listOfAnimals = new TypeToken<ArrayList<Animal>>() {}.getType();

RuntimeTypeAdapterFactory<Animal> adapter = RuntimeTypeAdapterFactory.of(Animal.class)
.registerSubtype(Dog.class)
.registerSubtype(Cow.class);

Gson gson = new GsonBuilder().registerTypeAdapterFactory(adapter).create();

List<Animal> outList = gson.fromJson(inputString, listOfAnimals);

assertEquals(2, outList.size());
assertTrue(outList.get(0) instanceof Dog);
}
}
Loading

0 comments on commit c2cb4d4

Please sign in to comment.