Fixed [JACKSON-796]
diff --git a/release-notes/CREDITS b/release-notes/CREDITS index 4d1bea8..d4b30f5 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS
@@ -871,3 +871,7 @@ * Reported [JACKSON-778], provided test case: Incorrect detection of generic types with TypeReference [1.9.5] + +Christopher Brown: + * Reported [JACKSON-796]: Problems with byte[] conversion to/from JsonNode. + [1.9.5]
diff --git a/release-notes/VERSION b/release-notes/VERSION index 9eb8efd..7dd58cc 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION
@@ -20,6 +20,8 @@ * [JACKSON-779]: Problems with multi-byte UTF-8 chars in JSON comments (reported by Alexander K) * [JACKSON-789]: Add support for 'java.nio.charset.Charset' + * [JACKSON-796]: Problems with byte[] conversion to/from JsonNode. + (reported by Christopher B) ------------------------------------------------------------------------ === History: ===
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/std/JsonNodeDeserializer.java b/src/mapper/java/org/codehaus/jackson/map/deser/std/JsonNodeDeserializer.java index 41b2164..eabb1d6 100644 --- a/src/mapper/java/org/codehaus/jackson/map/deser/std/JsonNodeDeserializer.java +++ b/src/mapper/java/org/codehaus/jackson/map/deser/std/JsonNodeDeserializer.java
@@ -253,7 +253,19 @@ return deserializeObject(jp, ctxt, nodeFactory); case VALUE_EMBEDDED_OBJECT: - return nodeFactory.POJONode(jp.getEmbeddedObject()); + // [JACKSON-796] + { + Object ob = jp.getEmbeddedObject(); + if (ob == null) { // should this occur? + return nodeFactory.nullNode(); + } + Class<?> type = ob.getClass(); + if (type == byte[].class) { // most common special case + return nodeFactory.binaryNode((byte[]) ob); + } + // any other special handling needed? + return nodeFactory.POJONode(ob); + } case VALUE_STRING: return nodeFactory.textNode(jp.getText());
diff --git a/src/mapper/java/org/codehaus/jackson/node/BinaryNode.java b/src/mapper/java/org/codehaus/jackson/node/BinaryNode.java index 1ce062e..198f0b4 100644 --- a/src/mapper/java/org/codehaus/jackson/node/BinaryNode.java +++ b/src/mapper/java/org/codehaus/jackson/node/BinaryNode.java
@@ -17,6 +17,12 @@ final byte[] _data; + /* + /********************************************************** + /* Construction + /********************************************************** + */ + public BinaryNode(byte[] data) { _data = data; @@ -54,6 +60,12 @@ return new BinaryNode(data, offset, length); } + /* + /********************************************************** + /* General type coercions + /********************************************************** + */ + @Override public JsonToken asToken() { /* No distinct type; could use one for textual values, @@ -83,6 +95,12 @@ return Base64Variants.getDefaultVariant().encode(_data, false); } + /* + /********************************************************** + /* Public API, serialization + /********************************************************** + */ + @Override public final void serialize(JsonGenerator jg, SerializerProvider provider) throws IOException, JsonProcessingException
diff --git a/src/mapper/java/org/codehaus/jackson/node/POJONode.java b/src/mapper/java/org/codehaus/jackson/node/POJONode.java index f6fbe6e..4f45a67 100644 --- a/src/mapper/java/org/codehaus/jackson/node/POJONode.java +++ b/src/mapper/java/org/codehaus/jackson/node/POJONode.java
@@ -28,6 +28,16 @@ @Override public boolean isPojo() { return true; } + @Override + public byte[] getBinaryValue() + throws IOException + { + if (_value instanceof byte[]) { + return (byte[]) _value; + } + return super.getBinaryValue(); + } + /* /********************************************************** /* General type coercions
diff --git a/src/test/org/codehaus/jackson/node/TestConversions.java b/src/test/org/codehaus/jackson/node/TestConversions.java index c288a81..c2f1414 100644 --- a/src/test/org/codehaus/jackson/node/TestConversions.java +++ b/src/test/org/codehaus/jackson/node/TestConversions.java
@@ -150,29 +150,33 @@ Assert.assertArrayEquals(inputData, result.data); } - public void testEmbeddedObject() throws Exception + public void testBinaryData() throws Exception { ObjectMapper mapper = new ObjectMapper(); TokenBuffer buf = new TokenBuffer(mapper); - buf.writeObject(new byte[0]); + buf.writeObject(new byte[3]); JsonNode node = mapper.readTree(buf.asParser()); - assertTrue(node.isPojo()); - assertEquals(byte[].class, ((POJONode) node).getPojo().getClass()); +// assertTrue(node.isBinary()); + byte[] data = node.getBinaryValue(); + assertNotNull(data); + assertEquals(3, data.length); } + private final Object MARKER = new Object(); + public void testEmbeddedObjectInArray() throws Exception { ObjectMapper mapper = new ObjectMapper(); TokenBuffer buf = new TokenBuffer(mapper); buf.writeStartArray(); - buf.writeObject(new byte[0]); + buf.writeObject(MARKER); buf.writeEndArray(); JsonNode node = mapper.readTree(buf.asParser()); assertTrue(node.isArray()); assertEquals(1, node.size()); JsonNode n = node.get(0); assertTrue(n.isPojo()); - assertEquals(byte[].class, ((POJONode) n).getPojo().getClass()); + assertSame(MARKER, ((POJONode) n).getPojo()); } public void testEmbeddedObjectInObject() throws Exception @@ -181,14 +185,14 @@ TokenBuffer buf = new TokenBuffer(mapper); buf.writeStartObject(); buf.writeFieldName("pojo"); - buf.writeObject(new byte[0]); + buf.writeObject(MARKER); buf.writeEndObject(); JsonNode node = mapper.readTree(buf.asParser()); assertTrue(node.isObject()); assertEquals(1, node.size()); JsonNode n = node.get("pojo"); assertTrue(n.isPojo()); - assertEquals(byte[].class, ((POJONode) n).getPojo().getClass()); + assertSame(MARKER, ((POJONode) n).getPojo()); } }
diff --git a/src/test/org/codehaus/jackson/smile/TestSmileAsTree.java b/src/test/org/codehaus/jackson/smile/TestSmileAsTree.java new file mode 100644 index 0000000..8745c9b --- /dev/null +++ b/src/test/org/codehaus/jackson/smile/TestSmileAsTree.java
@@ -0,0 +1,36 @@ +package org.codehaus.jackson.smile; + +import org.junit.Assert; + +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.map.*; +import org.codehaus.jackson.node.*; + +public class TestSmileAsTree extends SmileTestBase +{ + public void testSimple() throws Exception + { + // create the serialized JSON with byte array + ObjectMapper mapper = new ObjectMapper(new SmileFactory()); + + ObjectNode top1 = mapper.createObjectNode(); + ObjectNode foo1 = top1.putObject("foo"); + foo1.put("bar", "baz"); + final String TEXT = "Caf\u00e9 1\u20ac"; + final byte[] TEXT_BYTES = TEXT.getBytes("UTF-8"); + foo1.put("dat", TEXT_BYTES); + + byte[] doc = mapper.writeValueAsBytes(top1); + // now, deserialize + JsonNode top2 = mapper.readValue(doc, JsonNode.class); + JsonNode foo2 = top2.get("foo"); + assertEquals("baz", foo2.get("bar").getTextValue()); + + JsonNode datNode = foo2.get("dat"); + if (!datNode.isBinary()) { + fail("Expected binary node; got "+datNode.getClass().getName()); + } + byte[] bytes = datNode.getBinaryValue(); + Assert.assertArrayEquals(TEXT_BYTES, bytes); + } +}