4

Note: Jackson 2.1.x.

The problem is quite simple but I could not find a solution so far. I have browsed through existing documentation etc and could not find an answer.

The base class is this:

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "op")

@JsonSubTypes({
    @Type(name = "add", value = AddOperation.class),
    @Type(name = "copy", value = CopyOperation.class),
    @Type(name = "move", value = MoveOperation.class),
    @Type(name = "remove", value = RemoveOperation.class),
    @Type(name = "replace", value = ReplaceOperation.class),
    @Type(name = "test", value = TestOperation.class)
})

public abstract class JsonPatchOperation
{
    /*
     * Note: no need for a custom deserializer, Jackson will try and find a
     * constructor with a single string argument and use it
     */
    protected final JsonPointer path;

    protected JsonPatchOperation(final JsonPointer path)
    {
        this.path = path;
    }

    public abstract JsonNode apply(final JsonNode node)
        throws JsonPatchException;

    @Override
    public String toString()
    {
        return "path = \"" + path + '"';
    }
}

And the problematic class is this:

public abstract class PathValueOperation
    extends JsonPatchOperation
{
    protected final JsonNode value;

    protected PathValueOperation(final JsonPointer path, final JsonNode value)
    {
        super(path);
        this.value = value.deepCopy();
    }

    @Override
    public String toString()
    {
        return super.toString() + ", value = " + value;
    }
}

When I try to deserialize:

{ "op": "add", "path": "/x", "value": null }

I'd like the null value to be deserialized as a NullNode, not Java null. And I couldn't find a way to do it so far.

How do you achieve that?

(note: all constructors of concrete classes are @JsonCreators with the appropriate @JsonProperty annotations -- they work without problem, my only problem is JSON null handling)

fge
  • 119,121
  • 33
  • 254
  • 329

1 Answers1

8

OK, well, I haven't read the documentation enough, and it is in fact very simple.

There is a JsonNodeDeserializer implementation of JsonDeserializer, which you can extend. And JsonDeserializer has a.getNullValue() method.

So, a custom deserializer was in order:

public final class JsonNullAwareDeserializer
    extends JsonNodeDeserializer
{
    @Override
    public JsonNode getNullValue()
    {
        return NullNode.getInstance();
    }
}

And, in the problematic class:

@JsonDeserialize(using = JsonNullAwareDeserializer.class)
protected final JsonNode value;
fge
  • 119,121
  • 33
  • 254
  • 329
  • For what it is worth, this is probably a bug, reported now at https://github.com/FasterXML/jackson-databind/issues/186 – StaxMan Mar 08 '13 at 20:42