jackson-databind
jackson-databind copied to clipboard
JsonSerialize(Typing.DYNAMIC) in some cases does not redefine MapperFeature.USE_STATIC_TYPING
As unit test output shows, annotation overrides mapper feature only for:
- single field (
annotatedValue
)
And it's ignored for:
- annotated collection (
annotatedList
) - annotated class field (
dynamicValue
) - annotated class collection (
dynamicList
)
This is not expected behavior (for annotated list field, at least), since MapperFeature#USE_STATIC_TYPING says that:
This global default value can be overridden at class, method or field level by using JsonSerialize.typing() annotation property.
Test bellow is written in Kotlin, sorry for that. Was tested with Jackson 2.8.6
package com.testing.jackson
import com.fasterxml.jackson.databind.MapperFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import org.junit.Test
import java.util.*
import kotlin.test.assertEquals
abstract class Base { val a = 1 }
class Derived : Base() { val b = 2 }
@JsonSerialize(typing = JsonSerialize.Typing.DYNAMIC)
abstract class BaseDynamic { val a = 1 }
class DerivedDynamic : BaseDynamic() { val b = 2 }
class Mutter {
val value: Base = Derived()
@JsonSerialize(typing = JsonSerialize.Typing.DYNAMIC)
val annotatedValue: Base = Derived()
val dynamicValue: BaseDynamic = DerivedDynamic()
val list = ArrayList<Base>().apply { this.add(Derived()) }
@JsonSerialize(typing = JsonSerialize.Typing.DYNAMIC)
val annotatedList = ArrayList<Base>().apply { this.add(Derived()) }
val dynamicList = ArrayList<BaseDynamic>().apply { this.add(DerivedDynamic()) }
}
class jackson_typing_fails {
@Test fun go() {
val mapper = ObjectMapper()
.enable(MapperFeature.USE_STATIC_TYPING)
// .enable(SerializationFeature.INDENT_OUTPUT)
val writer = mapper.writerFor(Mutter::class.java)
val v = Mutter()
val s = writer.writeValueAsString(v)
// println(s)
val EXPECTED = """{"value":{"a":1},"annotatedValue":{"a":1,"b":2},"dynamicValue":{"a":1,"b":2},"list":[{"a":1}],"annotatedList":[{"a":1,"b":2}],"dynamicList":[{"a":1,"b":2}]}"""
assertEquals(EXPECTED, s)
}
}
org.junit.ComparisonFailure:
Expected :{"value":{"a":1},"annotatedValue":{"a":1,"b":2},"dynamicValue":{"a":1,"b":2},"list":[{"a":1}],"annotatedList":[{"a":1,"b":2}],"dynamicList":[{"a":1,"b":2}]}
Actual :{"value":{"a":1},"annotatedValue":{"a":1,"b":2},"dynamicValue":{"a":1},"list":[{"a":1}],"annotatedList":[{"a":1}],"dynamicList":[{"a":1}]}