Jackson SNAKE_CASE How to generate underscore in field names before number

Viewed 386

I have the next peace of code

    @Test
    fun `simple test`() {
        val objectMapper = ObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
            .registerModule(KotlinModule())

        val value = objectMapper.writeValueAsString(MyClass(myField1 = "something", myField2 = "something2"))
        assertNotNull(value)
    }

    data class MyClass (
        val myField1: String? = null,
        @JsonProperty("my_field_2")
        val myField2: String? = null,
    )

the result of deserialization is next

{"my_field1":"something","my_field_2":"something2"}

Is it possible to configure objectMapper to automatically populate _ value, before digits in object property names, without specifying it in @JsonProperty?

1 Answers

Yes, this is possible using a PropertyNamingStrategy:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)

Note that you named your snake-case fields inconsistently, because there is my_field1 without a _ before the digit, and my_field_2 with a _ before the digit. The configuration above using PropertyNamingStrategies.SNAKE_CASE works fine for the first naming (like in my_field1).

If you want to use the second naming (like in my_field_2), then you would have to write your own naming strategy like this:

class MySnakeCaseStrategy : NamingBase() {
    override fun translate(input: String?): String? =
        if (input == null) null
        else "([A-Z]+|[0-9]+)".toRegex().replace(input) { "_${it.groupValues[1]}".lowercase() }
}

That naming strategy can then be used to configure your object-mapper:

objectMapper.setPropertyNamingStrategy(MySnakeCaseStrategy())

I do not know if and how it would be possible to support both naming strategies at the same time.

Related