The best way to handle unknown enum values using Jackson

In this article, I want to show you how to handle enums using Jackson. It is not as easy as it seems. Jackson can’t deserialize unknown enum values by default. You have to decide what to do. If you don’t, your application will fail the moment external resource changes and an enum’s values extend.

How to handle unknown values?

Since Jackson 2.0, you can use READ_UNKNOWN_ENUM_VALUES_AS_NULL feature. Still, you will have to handle null when an unknown value appears in deserialized enum.

Since 2.8, there is a better way – READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE. Thanks to this feature, you can select a default value instead null value. Let’s see how it will look.

Provided examples are in Kotlin and use jackson-module-kotlin 2.12+.

enum class Color {
    RED, GREEN, BLUE,
    @JsonEnumDefaultValue UNKNOWN
}

data class Pixel(val color: Color)

Don’t forget to enable READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, when configuring ObjectMapper.

val objectMapper = jacksonMapperBuilder()
    .enable(READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE)
    .build()

That’s the way to handle enums to avoid dealing with errors when enum values extend.

when (objectMapper.readValue<Pixel>(jsonString).color) {
    Color.RED -> print("Handle red")
    Color.GREEN -> print("Handle green")
    Color.BLUE -> print("Handle blue")
    Color.UNKNOWN -> print("Handle unknown")
}

How to handle no value or null?

I showed you how to handle unknown values. That doesn’t solve deserializing JSON with no color property or color set to null value. In Kotlin, we can set the color property nullable. As before, you will have to handle this situation. If you want to avoid it, you can use a default value as well.

data class Pixel(
    @JsonSetter(nulls = Nulls.AS_EMPTY) 
    val color: Color = Color.UNKNOWN
)

@JsonSetter transforms null to an empty value. This way when the color property is unset, Color.UNKNOWN is used instead.

I prepared a repository that puts together everything I showed you in this article. You can see the example code here.

comments powered by Disqus