您必须在 Jackson 上使用过时的版本(或者可能是 Java 版本,而不是 Kotlin?)。我已经使用"com.fasterxml.jackson.module:jackson-module-kotlin:2.10.+"
(解析为 2.10.1)检查了这一点。
我已经声明了两个类:
class MyClass {
var a: Int = 42
set(value) {
val changed = field != value
field = value
if (changed) notifyListener(field)
}
private fun notifyListener(field: Any?) {
println("changed: $field")
}
}
class MyDelegatedClass {
var a: Int by NotifyUi(42)
private inner class NotifyUi<T>(initialValue: T) : ObservableProperty<T>(initialValue) {
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) {
notifyListener(newValue)
}
}
private fun notifyListener(field: Any?) {
println("changed: $field")
}
}
我的主要功能:
fun main() {
val noDelegate = MyClass()
val delegated = MyDelegatedClass()
val mapper = ObjectMapper().registerKotlinModule()
// Deserialization
val noDelegateValue = mapper.writeValueAsString(noDelegate)
val delegatedValue = mapper.writeValueAsString(delegated)
println("No delegate:\t$noDelegateValue")
println("With delegate\t$delegatedValue")
// Serialization
val noDelegateObject = mapper.readValue<MyClass>("{\"a\":42}".trimIndent())
val delegateObject = mapper.readValue<MyDelegatedClass>("{\"a\":42}".trimIndent())
}
输出:
No delegate: {"a":42}
With delegate {"a":42}
changed: 42
当我们使用委托属性时,我们甚至可以看到委托的输出:)(我相信这是一个副作用,实际上应该被视为错误)
因此,处理代表是杰克逊的开箱即用功能(我不确定从什么时候开始,但我在以前参与的旧项目中使用了lazy
代表jackson
,代表没有问题)。
如何忽略委托属性?
因此,您不能将JsonIgnore
注释应用于委托字段,因为您将获得This annotation is not applicable to target 'member property with delegate'
. 但是,您可以定义应应用注释的范围。下面的例子:
class MyDelegateClass {
@get:JsonIgnore // or set:
val a: Int by NotifyUi(42)
}
不幸的是,它似乎有点坏了,因为您可以使用get:
orset:
并且它不仅适用于 getter 或 setter,而且适用于两者。