Ensured that a custom handler is not visited during deserialization.

Ensured that JsonTreeNavigator can handle null values as children of JsonObject. This is now possible since Gson exposes toJson(JsonElement) method to which the user can pass a JsonElement with null values.
This commit is contained in:
Inderjeet Singh 2009-10-06 01:15:28 +00:00
parent ff74224815
commit 1da3ef9891
6 changed files with 121 additions and 13 deletions

View File

@ -69,7 +69,9 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
Type objType = objTypePair.getType();
JsonDeserializer deserializer = deserializers.getHandlerFor(objType);
if (deserializer != null) {
target = (T) deserializer.deserialize(json, objType, context);
if (json != null && !json.isJsonNull()) {
target = (T) deserializer.deserialize(json, objType, context);
}
return true;
}
return false;

View File

@ -112,8 +112,10 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
@SuppressWarnings("unchecked")
JsonDeserializer deserializer = deserializers.getHandlerFor(actualTypeOfField);
if (deserializer != null) {
Object value = deserializer.deserialize(child, actualTypeOfField, context);
f.set(parent, value);
if (child != null && !child.isJsonNull()) {
Object value = deserializer.deserialize(child, actualTypeOfField, context);
f.set(parent, value);
}
return true;
}
return false;

View File

@ -34,7 +34,7 @@ final class JsonTreeNavigator {
}
public void navigate(JsonElement element) throws IOException {
if (element.isJsonNull()) {
if (element == null || element.isJsonNull()) {
visitor.visitNull();
} else if (element.isJsonArray()) {
JsonArray array = element.getAsJsonArray();
@ -68,7 +68,7 @@ final class JsonTreeNavigator {
*/
private boolean visitChild(JsonObject parent, String childName, JsonElement child,
boolean isFirst) throws IOException {
if (child.isJsonNull()) {
if (child == null || child.isJsonNull()) {
if (visitNulls) {
visitor.visitNullObjectMember(parent, childName, isFirst);
navigate(child.getAsJsonNull());
@ -93,7 +93,7 @@ final class JsonTreeNavigator {
* Returns true if the child was visited, false if it was skipped.
*/
private void visitChild(JsonArray parent, JsonElement child, boolean isFirst) throws IOException {
if (child.isJsonNull()) {
if (child == null || child.isJsonNull()) {
visitor.visitNullArrayMember(parent, isFirst);
navigate(child);
} else if (child.isJsonArray()) {

View File

@ -406,4 +406,72 @@ public class CustomTypeAdaptersTest extends TestCase {
assertEquals("Jacob", foo.part1);
assertEquals("Tomaw", foo.part2);
}
public void testEnsureCustomSerializerNotInvokedForNullValues() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(DataHolder.class, new DataHolderSerializer())
.create();
DataHolderWrapper target = new DataHolderWrapper(new DataHolder("abc"));
String json = gson.toJson(target);
assertEquals("{\"wrappedData\":{\"myData\":\"abc\"}}", json);
}
public void testEnsureCustomDeserializerNotInvokedForNullValues() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(DataHolder.class, new DataHolderDeserializer())
.create();
String json = "{wrappedData:null}";
DataHolderWrapper actual = gson.fromJson(json, DataHolderWrapper.class);
assertNull(actual.wrappedData);
}
private static class DataHolder {
@SuppressWarnings("unused")
final String data;
// For use by Gson
@SuppressWarnings("unused")
private DataHolder() {
this("");
}
public DataHolder(String data) {
this.data = data;
}
}
private static class DataHolderWrapper {
final DataHolder wrappedData;
// For use by Gson
@SuppressWarnings("unused")
private DataHolderWrapper() {
this(null);
}
public DataHolderWrapper(DataHolder data) {
this.wrappedData = data;
}
}
private static class DataHolderSerializer implements JsonSerializer<DataHolder> {
public JsonElement serialize(DataHolder src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.addProperty("myData", src.data);
return obj;
}
}
private static class DataHolderDeserializer implements JsonDeserializer<DataHolder> {
public DataHolder deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObj = json.getAsJsonObject();
JsonElement jsonElement = jsonObj.get("data");
if (jsonElement == null || jsonElement.isJsonNull()) {
return new DataHolder(null);
}
return new DataHolder(jsonElement.getAsString());
}
}
}

View File

@ -16,15 +16,10 @@
package com.google.gson.functional;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import junit.framework.TestCase;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import com.google.gson.JsonObject;
import com.google.gson.common.TestTypes.ArrayOfObjects;
import com.google.gson.common.TestTypes.BagOfPrimitiveWrappers;
import com.google.gson.common.TestTypes.BagOfPrimitives;
@ -35,6 +30,12 @@ import com.google.gson.common.TestTypes.ClassWithTransientFields;
import com.google.gson.common.TestTypes.Nested;
import com.google.gson.common.TestTypes.PrimitiveArray;
import junit.framework.TestCase;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
/**
* Functional tests for Json serialization and deserialization of regular classes.
*
@ -401,4 +402,11 @@ public class ObjectTest extends TestCase {
String b = "";
String c = "";
}
public void testJsonObjectSerialization() {
Gson gson = new GsonBuilder().serializeNulls().create();
JsonObject obj = new JsonObject();
String json = gson.toJson(obj);
assertEquals("{}", json);
}
}

View File

@ -17,6 +17,8 @@
package com.google.gson.functional;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.common.TestTypes.BagOfPrimitives;
import com.google.gson.common.TestTypes.ClassWithTransientFields;
import com.google.gson.common.TestTypes.Nested;
@ -35,9 +37,16 @@ import java.util.List;
*/
public class PrintFormattingTest extends TestCase {
private Gson gson;
@Override
protected void setUp() throws Exception {
super.setUp();
gson = new Gson();
}
@SuppressWarnings("unchecked")
public void testCompactFormattingLeavesNoWhiteSpace() {
Gson gson = new Gson();
List list = new ArrayList();
list.add(new BagOfPrimitives());
list.add(new Nested());
@ -48,6 +57,25 @@ public class PrintFormattingTest extends TestCase {
assertContainsNoWhiteSpace(json);
}
public void testJsonObjectWithNullValues() {
JsonObject obj = new JsonObject();
obj.addProperty("field1", "value1");
obj.addProperty("field2", (String) null);
String json = gson.toJson(obj);
assertTrue(json.contains("field1"));
assertFalse(json.contains("field2"));
}
public void testJsonObjectWithNullValuesSerialized() {
gson = new GsonBuilder().serializeNulls().create();
JsonObject obj = new JsonObject();
obj.addProperty("field1", "value1");
obj.addProperty("field2", (String) null);
String json = gson.toJson(obj);
assertTrue(json.contains("field1"));
assertTrue(json.contains("field2"));
}
private static void assertContainsNoWhiteSpace(String str) {
for (char c : str.toCharArray()) {
assertFalse(Character.isWhitespace(c));