Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excluding NullNode when serializing a Jackson JSON tree model

Tags:

java

json

jackson

I have a pojo type that needs to have specific numeric values set to a special string when it's serialized. These values will always be null, possibly pretty deep into a hierarchy.

To accomplish this I first convert the pojo to a JsonNode with nulls intact to preserve property order, then I follow a path through the structure to set some strings and create nodes as necessary. Finally, I have the ObjectMapper serialize the JsonNode to a string. The logic looks something like this:

ObjectMapper nonNullMapper = new ObjectMapper();
nonNullMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

ObjectMapper includeAllMapper = new ObjectMapper();
includeAllMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

// NullNodes create stubs to maintain property order
JsonNode node = includeAllMapper.valueToTree(pojoInstance);
insertStrings(node);

String json = nonNullMapper.writeValueAsString(node); 
// Halp, there's still nulls

Note that I'm aware there's a @JsonInclude annotation so I don't actually need two mappers, but it turns out that I want to serialize the pojo instances without nulls elsewhere, so I can't use it to my knowledge.

Anyway, how can I avoid having the NullNodes serialized into my string of json? I've found two approaches so far:

  1. Convert to a Map and then serialize to a String, with SerializationFeature.WRITE_NULL_MAP_VALUES disabled. This seems inefficient and hacky.
  2. Remove NullNode instances manually before serializing the JsonNode. Seems like it shouldn't be necessary given the support for excluding nulls for pojos and maps, and it adds (perhaps?) unneeded complexity.

I tried registering a JsonSerializer for NullNode, but it doesn't appear to get used. I notice that NullNode itself implements JsonSerializable, which simply delegates to the SerializerProvider's null value serializer. I hesitate to attempt to overwrite this and I feel like the null filtering should be taking place before the values are serialized, but I didn't dig deep enough to understand exactly how it works.

Is there a better way?

like image 533
Shaun Avatar asked Feb 02 '14 14:02

Shaun


People also ask

How do I ignore null values in JSON response Jackson?

You can ignore null fields at the class level by using @JsonInclude(Include. NON_NULL) to only include non-null fields, thus excluding any attribute whose value is null. You can also use the same annotation at the field level to instruct Jackson to ignore that field while converting Java object to json if it's null.

How do I ignore null properties in JSON?

In order to ignore null fields at the class level, we use the @JsonInclude annotation with include. NON_NULL. Let's take an example to understand how we can use @JsonInclude annotation to ignore the null fields at the class level.

Does Jackson use Java serialization?

XML Serialization and Deserialization with Jackson This short tutorial shows how the Jackson library can be used to serialize Java object to XML and deserialize them back to objects.


2 Answers

Further to @StaxMan's answer, here's some code to prune the NullNodes:

public static void stripNulls(JsonNode node) {
    Iterator<JsonNode> it = node.iterator();
    while (it.hasNext()) {
        JsonNode child = it.next();
        if (child.isNull())
            it.remove();
        else
            stripNulls(child);
    }
}
like image 187
Neil Avatar answered Sep 23 '22 17:09

Neil


I don't know of a good solution, but just thought I point out that JSON Tree Model (JsonNode) is used to present exact JSON structure; and as such, very few of general features for filtering or transformation are applied. It is very close to WYSIWYG.

Because of this, I would probably rather just traverse the Tree and prune NullNodes explicitly. Trying to configure Jackson itself to do this ends up being more work than explicit removal of nodes.

like image 30
StaxMan Avatar answered Sep 24 '22 17:09

StaxMan