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:
SerializationFeature.WRITE_NULL_MAP_VALUES
disabled. This seems inefficient and hacky.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?
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.
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.
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.
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);
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With