javajacksonjsonparserjackson2jsonnode

Jackson 2.6.0 JsonParser#getCurrentValue() returns null instead of value of JSON property


In Jackson 2.6.0, JsonParser#getCurrentValue() returns null instead of the value of the currently parsed JSON property.

The example method at the end of this question prints:

a
null

But I expect it to print:

a
b

Why is null printed instead of b?

How can I get the value of the current JSON property as an Object, so that it will return a String, Boolean, Integer, Long, Double, Float, BigDecimal, etc., or null, as appropriate?

I know that there'd have to be an algorithm that determines when to return, e.g., 1 as an Integer, Long, Double, BigDecimal, or some other Number subclass, but I imagine that there'd be a default algorithm that could be replaced by a custom algorithm.

Example method:

public static void main(final String[] args) throws IOException {
    final JsonParser jsonParser = new JsonFactory().createParser("{\"a\":\"b\"}");

    while (jsonParser.nextValue() != null) {
        final Object value = jsonParser.getCurrentValue();
        final String name  = jsonParser.getCurrentName();
        if (name != null) {
            System.out.println(name + "\n" + value);
        }
    }
}

Solution

  • Couple of different things at work here.

    First: getCurrentValue() is NOT maintained by low-level streaming API itself at all, so your code would never see a non-null value. Instead, it is managed by databinding (higher level), based on Java POJO Objects, which are only handled at databinding. The reason methods themselves are in JsonParser and JsonGenerator is due to practical limitations, as parser/generator are passed through processing, are available to JsonSerializer / JsonDeserializer, and have hierarchic scope: conceptually this information would belong at databinding level completely.

    If you want to only operate on streaming level, these methods will not be of use to you. You need to keep track of all the information yourself. Alternatively, perhaps you should bind JSON as JsonNode using ObjectMapper, and then traverse the logical in-memory tree. Streaming processing minimizes amount of state it keeps, which is not necessarily very convenient for most operations.