You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
During the serialization of a is-getter property with continuous capital letters (e.g. isUSDListing), the serialized property become
usdListing" instead of "isUSDListing"
To Reproduce
data class SampleWithIsGetter (
val isUSDListing: Boolean
)
fun main() {
runFailed()
runWorkaround()
}
fun runFailed(){
val sample = SampleWithIsGetter(true)
val json = jacksonObjectMapper().writeValueAsString(sample)
println(
"""
Example to show that jackson serialization will fail when both conditions are fulfilled
1. attribute name starts with a "is"
2. attribute name after the "is" has continuous capital letters
The serialized json shows attribute name as "usdListing" instead of "isUSDListing"
""".trimIndent()
)
println(json)
assertThrows<MismatchedInputException> { jacksonObjectMapper().readValue(json, SampleWithIsGetter::class.java) }
}
fun runWorkaround(){
val sample = SampleWithIsGetter(true)
val objectMapper = jacksonMapperBuilder().configure(MapperFeature.USE_STD_BEAN_NAMING, true).build()
val json = objectMapper.writeValueAsString(sample)
val deserialized = objectMapper.readValue(json, SampleWithIsGetter::class.java)
println(
"""
Workaround solution is to set the MapperFeature - USE_STD_BEAN_NAMING to true
USE_STD_BEAN_NAMING will ensure attribute naming will ensure attribute name will not
be lower-cased if it is followed by upper-cased letters.
Meaning, getURL() will return "URL" instead of "url"
USE_STD_BEAN_NAMING is false by default for backward compatibility
""".trimIndent()
)
println(json)
assertThat(sample, equalTo(deserialized))
}
Expected behavior
fun expectedBehavior(){
val sample = SampleWithIsGetter(true)
val json = jacksonObjectMapper().writeValueAsString(sample)
val deserialized = objectMapper.readValue(json, SampleWithIsGetter::class.java)
assertThat(sample, equalTo(deserialized))
}
In POJOPropertiesCollector#collectAll in jackson-databind, it first gets all the properties in the class with _addFields(), then it gets all the methods in the class with _addMethods(). In both the _addFields() and _addMethods(), if the field or method starts with "is", it will try to get a rename of the property by removing the "is". So if the field is "isUSD", it will return either "usd" or "USD", depending if the MapperFeature.USE_STD_BEAN_NAMING is true. Then in either the _addGetterMethod() or _addSetterMethod() called from the _addMethods(), it will map the method to the field. In order to map the getter/setter method correctly, the rename method called by both _addMethods() and _addFields() should be the same.
However, the rename method in _addFields() is calling KotlinNamesAnnotationIntrospector#findRenameByField() in jackson-module-kotlin, which in turn calls BeanUtil.stdManglePropertyName(), but _addMethods calls DefaultAccessorNamingStrategy#findNameForIsGetter() in jackson-databind. The root cause of this issue is that DefaultAccessorNamingStrategy#findNameForIsGetter() will consider the MapperFeature.USE_STD_BEAN_NAMING to decide whether stdManglePropertyName or legacyManglePropertyName should be used, but KotlinNamesAnnotationIntrospector#findRenameByField() will just use stdManglePropertyName directly.
Should the KotlinNamesAnnotationIntrospector use DefaultAccessorNamingStrategy#findNameForIsGetter() instead? Since the BeanUtil has a deprecated okNameForIsGetter() which states that it is replaced by the AccesorNamingStrategy.
I verified on branch 2.15 and the submitted test case seems to be fixed.
This is probably a duplicate of #340, which appears to have been fixed in #641.
Describe the bug
During the serialization of a is-getter property with continuous capital letters (e.g. isUSDListing), the serialized property become
usdListing" instead of "isUSDListing"
To Reproduce
Expected behavior
Versions
Kotlin: 1.6.10
Jackson-module-kotlin: 2.13.1
Jackson-databind: 2.13.1
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: