jackson-module-kotlin: @JsonProperty is ignored on data class properties with names starting with "is"

Hi,

I’ve got a data class with a boolean property called isPublic. This property needs to be called exactly like that in JSON. However, since the property name starts with is, the prefix is stripped from the name. Adding @JsonProperty("isPublic") does not work either:

class JacksonTest {

    @Test
    fun serializeTest(){
        val objectMapper = ObjectMapper()
        objectMapper.registerKotlinModule()

        val instance = MyClass(true)
        val json = objectMapper.writeValueAsString(instance)

        assertEquals("""{"isPublic":true}""", json.replace("""\s+""".toRegex(), ""))
    }

    data class MyClass(
        @JsonProperty("isPublic")
        val isPublic: Boolean
    )

}

… fails with an assertion error:

java.lang.AssertionError: Expected <{"isPublic":true}>, actual <{"public":true}>.

It doesn’t matter what you pass into the @JsonProperty annotation, in the JSON output the field is always (!!) called public.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 17 (4 by maintainers)

Commits related to this issue

Most upvoted comments

Same! Any solution? I thought that I made mistake somewhere in the configuration.

My code:

data class PlayerResponse(
  @JsonProperty("abc")
  val accountId: Long,

  @JsonProperty("def")
  val isAdmin: Boolean,

  @JsonProperty("ghi")
  val isConnected: Boolean
)

val mapper = jacksonObjectMapper().apply {
    registerModule(ParameterNamesModule())
    registerModule(Jdk8Module())
    registerModule(JavaTimeModule())
  }

  val json = mapper.writeValueAsString(PlayerResponse(1, true, true))

Response:

{"abc":1,"admin":true,"connected":true}

Use @get:JsonProperty(“abc”) and @param:JsonProperty(“abc”) annotation on Boolean field instead of @JsonProperty(“abc”)

Changing @JsonProperty(“fieldname”) to @field:JsonProperty(“fieldname”) resolves the issue for data classes’ “is” (Boolean) properties.

The only workaround I’ve found is to rename the field in your (data) class, and then expose it with @JsonProperty like so:

data class MyDTO(

    @JsonProperty("isConnected")
    val connected: Boolean   // do NOT call this "isConnected"!

)

That worked for me, YMMV.

Thanks @MaksimRT Just adding @get:JsonProperty(“abc”) worked for me. I did not add @param:JsonProperty(“abc”) and it still worked. Is there any specific reason why you added @param:JsonProperty(“abc”) as well?

Hi, you are welcome)

What version of the library do you use?)

Same! Any solution? I thought that I made mistake somewhere in the configuration.

My code:

data class PlayerResponse(
  @JsonProperty("abc")
  val accountId: Long,

  @JsonProperty("def")
  val isAdmin: Boolean,

  @JsonProperty("ghi")
  val isConnected: Boolean
)

val mapper = jacksonObjectMapper().apply {
    registerModule(ParameterNamesModule())
    registerModule(Jdk8Module())
    registerModule(JavaTimeModule())
  }

  val json = mapper.writeValueAsString(PlayerResponse(1, true, true))

Response:

{"abc":1,"admin":true,"connected":true}