Skip to content

ObjectMapper's .valueToTree() wraps JsonNode objects into a POJONode #433

@fge

Description

@fge

Affected versions: 2.2.3, 2.3.2.

Let us take these two sample classes:

public final class BasicBean
{
    private String foo;

    public void setFoo(final String foo)
    {
        this.foo = foo;
    }

    public String getFoo()
    {
        return foo;
    }

    public static void main(final String... args)
    {
        final BasicBean foo = new BasicBean();
        foo.setFoo("bar");
        final ObjectMapper mapper = new ObjectMapper();
        final JsonNode node = mapper.valueToTree(foo);
        System.out.println(node.getNodeType());
        System.out.println(node);
    }
}

and this one:

public final class CustomSerializedPojo
    implements JsonSerializable
{
    private final ObjectNode node = JsonNodeFactory.instance.objectNode();

    public void setFoo(final String foo)
    {
        node.put("foo", foo);
    }

    @Override
    public void serialize(final JsonGenerator jgen,
        final SerializerProvider provider)
        throws IOException, JsonProcessingException
    {
        jgen.writeTree(node);
    }

    @Override
    public void serializeWithType(final JsonGenerator jgen,
        final SerializerProvider provider, final TypeSerializer typeSer)
        throws IOException, JsonProcessingException
    {
        typeSer.writeTypePrefixForObject(this, jgen);
        serialize(jgen, provider);
        typeSer.writeTypeSuffixForObject(this, jgen);
    }

    public static void main(final String... args)
    {
        final CustomSerializedPojo pojo = new CustomSerializedPojo();
        pojo.setFoo("bar");
        final ObjectMapper mapper = new ObjectMapper();
        final JsonNode node = mapper.valueToTree(pojo);
        System.out.println(node.getNodeType());
        if (node.getNodeType() == JsonNodeType.POJO) {
            final Object embedded = ((POJONode) node).getPojo();
            System.out.println(embedded.getClass());
            System.out.println(embedded);
        }
    }
}

The execution of the first main gives:

OBJECT
{"foo":"bar"}

However, the execution of the second one gives:

POJO
class com.fasterxml.jackson.databind.node.ObjectNode
{"foo":"bar"}

Therefore, if .valueToTree() is called on a class implementing JsonSerializable, it embeds the result of the serialization into a POJONode!

NOTE: I did check that it was the .serialize() method which was called and not .serializeWithType().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions