Excluding NullNode when serializing a Jackson JSON tree model

jackson, java, json

Solution

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 `NullNode`s explicitly. Trying to configure Jackson itself to do this ends up being more work than explicit removal of nodes.

Problem

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: - Convert to a Map and then serialize to a String, with `SerializationFeature.WRITE_NULL_MAP_VALUES` disabled. This seems inefficient and hacky. - 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?

Original source