(反)使用 jackson 序列化 kotlin 委托属性
(de)serializing kotlin delegate properties with jackson
我如何使用 jackson(反)序列化 kotlin 委托属性。
我有一个这样的class
class MyClass {
var a: Int = 42
set(value) {
val changed = field != value
field = value
if (changed) notifyListeners()
}
... and a dozen other properties that all follow this pattern ...
}
我想通过使用
来简化它
class MyClass {
var a: Int by NotifyUiOnChange(42)
...
private inner class NotifyUiOnChange<T>(initialValue: T) : ObservableProperty<T>(initialValue) {
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) {
notifyUiListeners()
}
}
}
但杰克逊会忽略 属性。
我怎样才能告诉 Jackson 序列化和反序列化 属性 呢?
然后我如何应用@JsonIgnore 注释(或类似的注释)?
您必须在 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
我们甚至可以在使用委托时看到委托的输出 属性 :)(我认为这是一个副作用,实际上应该被视为错误)
因此,处理委托是 jackson 中开箱即用的功能(我不确定从什么时候开始,但我在以前参与的旧项目中使用 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:
或 set:
并且它不适用于 getter 或 setter,但两者都适用.
我如何使用 jackson(反)序列化 kotlin 委托属性。 我有一个这样的class
class MyClass {
var a: Int = 42
set(value) {
val changed = field != value
field = value
if (changed) notifyListeners()
}
... and a dozen other properties that all follow this pattern ...
}
我想通过使用
来简化它class MyClass {
var a: Int by NotifyUiOnChange(42)
...
private inner class NotifyUiOnChange<T>(initialValue: T) : ObservableProperty<T>(initialValue) {
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) {
notifyUiListeners()
}
}
}
但杰克逊会忽略 属性。
我怎样才能告诉 Jackson 序列化和反序列化 属性 呢?
然后我如何应用@JsonIgnore 注释(或类似的注释)?
您必须在 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
我们甚至可以在使用委托时看到委托的输出 属性 :)(我认为这是一个副作用,实际上应该被视为错误)
因此,处理委托是 jackson 中开箱即用的功能(我不确定从什么时候开始,但我在以前参与的旧项目中使用 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:
或 set:
并且它不适用于 getter 或 setter,但两者都适用.