Merge pull request #423 from sergeymetallic/patch-1
Update CalendarSerializer.java
diff --git a/release-notes/CREDITS b/release-notes/CREDITS
index cb72ea5..4da5f72 100644
--- a/release-notes/CREDITS
+++ b/release-notes/CREDITS
@@ -111,4 +111,8 @@
* Contributed #407: Make array and Collection serializers use configured value null handler
(2.4.0)
+Cemalettin Koc: (cemo@github)
+
+ * Reported #353: Problems with polymorphic types, `JsonNode` (related to #88)
+ (2.4.0)
diff --git a/release-notes/VERSION b/release-notes/VERSION
index e86848c..3fc975c 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -3,6 +3,8 @@
#88: Prevent use of type information for `JsonNode` via default typing
(reported by electricmonk@github)
+#353: Problems with polymorphic types, `JsonNode` (related to #88)
+ (reported by cemo@github)
#381: Allow inlining/unwrapping of value from single-component JSON array
(contributed by yinzara@github)
#407: Properly use null handlers for value types when serializer Collection
diff --git a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
index 63ec3a9..2573804 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
@@ -222,7 +222,7 @@
TimeZone.getTimeZone("GMT"),
Base64Variants.getDefaultVariant() // 2.1
);
-
+
/*
/**********************************************************
/* Configuration settings, shared
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java
index 93a92fe..f205080 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java
@@ -30,16 +30,19 @@
if (cls == String.class) {
return DEFAULT_STRING_SERIALIZER;
}
- if (cls == Object.class) {
+ if (cls == Object.class || cls.isPrimitive() || Number.class.isAssignableFrom(cls)) {
return DEFAULT_KEY_SERIALIZER;
}
- // [JACKSON-606] special handling for dates...
if (Date.class.isAssignableFrom(cls)) {
return (JsonSerializer<Object>) DateKeySerializer.instance;
}
if (Calendar.class.isAssignableFrom(cls)) {
return (JsonSerializer<Object>) CalendarKeySerializer.instance;
}
+ /* 14-Mar-2014, tatu: Should support @JsonValue, as per #47; but that
+ * requires extensive introspection, and passing in more information
+ * to this method.
+ */
// If no match, just use default one:
return DEFAULT_KEY_SERIALIZER;
}
diff --git a/src/test/java/com/fasterxml/jackson/databind/node/TestJsonPointer.java b/src/test/java/com/fasterxml/jackson/databind/node/TestJsonPointer.java
index bf2da1e..e99356a 100644
--- a/src/test/java/com/fasterxml/jackson/databind/node/TestJsonPointer.java
+++ b/src/test/java/com/fasterxml/jackson/databind/node/TestJsonPointer.java
@@ -31,4 +31,19 @@
assertTrue(SAMPLE_ROOT.at("/Image/Depth").isMissingNode());
assertTrue(SAMPLE_ROOT.at("/Image/1").isMissingNode());
}
+
+ // To help verify [Core#133]; should be fine with "big numbers" as property keys
+ public void testLongNumbers() throws Exception
+ {
+
+ // First, with small int key
+ JsonNode root = objectMapper().readTree("{\"123\" : 456}");
+ JsonNode jn2 = root.at("/123");
+ assertEquals(456, jn2.asInt());
+
+ // and then with above int-32:
+ root = objectMapper().readTree("{\"35361706045\" : 1234}");
+ jn2 = root.at("/35361706045");
+ assertEquals(1234, jn2.asInt());
+ }
}
diff --git a/src/test/java/com/fasterxml/jackson/databind/node/TestTreeWithType.java b/src/test/java/com/fasterxml/jackson/databind/node/TestTreeWithType.java
new file mode 100644
index 0000000..d02ff8c
--- /dev/null
+++ b/src/test/java/com/fasterxml/jackson/databind/node/TestTreeWithType.java
@@ -0,0 +1,126 @@
+package com.fasterxml.jackson.databind.node;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+public class TestTreeWithType extends BaseMapTest
+{
+ public static class Foo {
+ public String bar;
+
+ public Foo() { }
+
+ public Foo(String bar) {
+ this.bar = bar;
+ }
+ }
+
+ // [Issue#353]
+ public class SavedCookie {
+ public String name, value;
+
+ public SavedCookie() { }
+ public SavedCookie(String n, String v) {
+ name = n;
+ value = v;
+ }
+ }
+
+ public class SavedCookieDeserializer extends JsonDeserializer<SavedCookie> {
+ @Override
+ public SavedCookie deserialize(JsonParser jsonParser, DeserializationContext ctxt)
+ throws IOException {
+ ObjectCodec oc = jsonParser.getCodec();
+ JsonNode node = oc.readTree(jsonParser);
+ return new SavedCookie(node.path("name").textValue(),
+ node.path("value").textValue());
+ }
+
+ @Override
+ public SavedCookie deserializeWithType(JsonParser jp, DeserializationContext ctxt,
+ TypeDeserializer typeDeserializer)
+ throws IOException, JsonProcessingException
+ {
+ return (SavedCookie) typeDeserializer.deserializeTypedFromObject(jp, ctxt);
+ }
+ }
+
+ /*
+ /**********************************************************
+ /* Unit tests
+ /**********************************************************
+ */
+
+ private final ObjectMapper MAPPER = new ObjectMapper();
+
+ public void testValueAsStringWithoutDefaultTyping() throws Exception {
+
+ Foo foo = new Foo("baz");
+ String json = MAPPER.writeValueAsString(foo);
+
+ JsonNode jsonNode = MAPPER.readTree(json);
+ assertEquals(jsonNode.get("bar").textValue(), foo.bar);
+ }
+
+ public void testValueAsStringWithDefaultTyping() throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
+
+ Foo foo = new Foo("baz");
+ String json = mapper.writeValueAsString(foo);
+
+ JsonNode jsonNode = mapper.readTree(json);
+ assertEquals(jsonNode.get("bar").textValue(), foo.bar);
+ }
+
+ public void testReadTreeWithDefaultTyping() throws Exception
+ {
+ final String CLASS = Foo.class.getName();
+
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL,
+ JsonTypeInfo.As.PROPERTY);
+ String json = "{\"@class\":\""+CLASS+"\",\"bar\":\"baz\"}";
+ JsonNode jsonNode = mapper.readTree(json);
+ assertEquals(jsonNode.get("bar").textValue(), "baz");
+ }
+
+ public void testValueToTreeWithoutDefaultTyping() throws Exception {
+
+ Foo foo = new Foo("baz");
+ JsonNode jsonNode = MAPPER.valueToTree(foo);
+ assertEquals(jsonNode.get("bar").textValue(), foo.bar);
+ }
+
+ public void testValueToTreeWithDefaultTyping() throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
+
+ Foo foo = new Foo("baz");
+ JsonNode jsonNode = mapper.valueToTree(foo);
+ assertEquals(jsonNode.get("bar").textValue(), foo.bar);
+ }
+
+ public void testIssue353() throws Exception
+ {
+ ObjectMapper mapper = new ObjectMapper();
+
+ mapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.NON_FINAL, "@class");
+
+ SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null, "TEST", "TEST"));
+ testModule.addDeserializer(SavedCookie.class, new SavedCookieDeserializer());
+ mapper.registerModule(testModule);
+
+ SavedCookie savedCookie = new SavedCookie("key", "v");
+ String json = mapper.writeValueAsString(savedCookie);
+ SavedCookie out = mapper.reader(SavedCookie.class).readValue(json);
+
+ assertEquals("key", out.name);
+ assertEquals("v", out.value);
+ }
+}
diff --git a/src/test/java/com/fasterxml/jackson/failing/TestMapJsonValueKey.java b/src/test/java/com/fasterxml/jackson/failing/TestMapJsonValueKey.java
index 0be19b3..2b76dd9 100644
--- a/src/test/java/com/fasterxml/jackson/failing/TestMapJsonValueKey.java
+++ b/src/test/java/com/fasterxml/jackson/failing/TestMapJsonValueKey.java
@@ -5,45 +5,40 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
-import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.test.BaseTest;
-public class TestMapJsonValueKey extends BaseTest
+// [Issue#47]
+public class TestMapJsonValueKey extends BaseMapTest
{
public static class Wat
{
private final String wat;
@JsonCreator
- Wat(String wat)
- {
+ Wat(String wat) {
this.wat = wat;
}
@JsonValue
- public String getWat()
- {
+ public String getWat() {
return wat;
}
@Override
- public String toString()
- {
- return "[Wat: " + wat + "]";
+ public String toString() {
+ return "(String)[Wat: " + wat + "]";
}
}
public void testMapJsonValueKey()
throws Exception
{
- Map<Wat, Boolean> map = new HashMap<Wat, Boolean>();
- map.put(new Wat("3"), true);
- map.put(new Wat("x"), false);
-
- TypeReference<Map<Wat, Boolean>> type = new TypeReference<Map<Wat, Boolean>>(){};
+ Map<Wat, Boolean> input = new HashMap<Wat, Boolean>();
+ input.put(new Wat("3"), true);
ObjectMapper mapper = new ObjectMapper();
- assertEquals(map, mapper.readValue(mapper.writeValueAsBytes(map), type));
+ String json = mapper.writeValueAsString(input);
+ assertEquals(aposToQuotes("{'3':'true'}"), json);
}
}
diff --git a/src/test/java/com/fasterxml/jackson/failing/TestTreeWithType.java b/src/test/java/com/fasterxml/jackson/failing/TestTreeWithType.java
deleted file mode 100644
index 5842792..0000000
--- a/src/test/java/com/fasterxml/jackson/failing/TestTreeWithType.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.fasterxml.jackson.failing;
-
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import com.fasterxml.jackson.databind.*;
-
-public class TestTreeWithType extends BaseMapTest
-{
- public static class Foo {
- public String bar;
-
- public Foo() { }
-
- public Foo(String bar) {
- this.bar = bar;
- }
- }
-
- /*
- /**********************************************************
- /* Unit tests
- /**********************************************************
- */
-
- private final ObjectMapper mapper = new ObjectMapper();
-
- public void testValueAsStringWithoutDefaultTyping() throws Exception {
-
- Foo foo = new Foo("baz");
- String json = mapper.writeValueAsString(foo);
-
- JsonNode jsonNode = mapper.readTree(json);
- assertEquals(jsonNode.get("bar").textValue(), foo.bar);
- }
-
- public void testValueAsStringWithDefaultTyping() throws Exception {
- mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
-
- Foo foo = new Foo("baz");
- String json = mapper.writeValueAsString(foo);
-
- JsonNode jsonNode = mapper.readTree(json);
- assertEquals(jsonNode.get("bar").textValue(), foo.bar);
- }
-
- public void testReadTreeWithDefaultTyping() throws Exception
- {
- final String CLASS = Foo.class.getName();
-
- mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL,
- JsonTypeInfo.As.PROPERTY);
- String json = "{\"@class\":\""+CLASS+"\",\"bar\":\"baz\"}";
- JsonNode jsonNode = mapper.readTree(json);
- assertEquals(jsonNode.get("bar").textValue(), "baz");
- }
-
- public void testValueToTreeWithoutDefaultTyping() throws Exception {
-
- Foo foo = new Foo("baz");
- JsonNode jsonNode = mapper.valueToTree(foo);
- assertEquals(jsonNode.get("bar").textValue(), foo.bar);
- }
-
- public void testValueToTreeWithDefaultTyping() throws Exception {
- mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
-
- Foo foo = new Foo("baz");
- JsonNode jsonNode = mapper.valueToTree(foo);
- assertEquals(jsonNode.get("bar").textValue(), foo.bar);
- }
-}