使用 Jackson JsonDeserializer 解码自定义对象
Decode custom object using Jackson JsonDeserializer
我是 Kotlin 的新手(来自 Swift),我有一个非常简单的 json,我需要将其解码为两个不同的 Kotlin class 基于一个字段json。如果字段是"type": "Square"
我想解码一个Square
class,如果字段是"type": "Rectangle",
我想解码一个Rectangle
class .
我需要解码的json是
{
"type": "Square",
"size": "1"
}
或
{
"type": "Rectangle",
"width": 1,
"length": 2
}
我的 .kt class 是这样定义的。我写了一个自定义 JsonDeserializer
但它似乎不起作用,因为 jp.readValueAs(Square::class.java)
返回 null。
@JsonDeserialize(using = Shape.Deserializer::class)
sealed class Shape {
enum class Type {
Rectangle,
Square
}
abstract val type: Type
data class Square(
val size: Int
) : Shape() {
override val type: Type = Type.Square
}
data class Rectangle(
val width: Int,
val length: Int
) : Shape() {
override val type: Type = Type.Rectangle
}
class Deserializer: JsonDeserializer<Shape>() {
override fun deserialize(jp: JsonParser, ctxt: DeserializationContext?): Shape {
var node = jp.readValueAsTree<JsonNode>()
return when(node.get("type").asText()) {
Type.Square.name ->
jp.readValueAs(Square::class.java)
Type.Rectangle.name ->
jp.readValueAs(Rectangle::class.java)
else -> throw JsonMappingException("")
}
}
}
}
我做错了什么?
干杯
回答我自己的问题:我认为可以使用 Shape
class 上的注释打开 type
属性,如下所示
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes(
value = [
JsonSubTypes.Type(value = Shape.Square::class, name = "Square"),
JsonSubTypes.Type(value = Shape.Rectangle::class, name = "Rectangle")
]
)
sealed class Shape {
enum class Type {
Rectangle,
Square
}
abstract val type: Type
data class Square(
val size: Int
) : Shape() {
override val type: Type = Type.Square
}
data class Rectangle(
val width: Int,
val length: Int
) : Shape() {
override val type: Type = Type.Rectangle
}
}
我是 Kotlin 的新手(来自 Swift),我有一个非常简单的 json,我需要将其解码为两个不同的 Kotlin class 基于一个字段json。如果字段是"type": "Square"
我想解码一个Square
class,如果字段是"type": "Rectangle",
我想解码一个Rectangle
class .
我需要解码的json是
{
"type": "Square",
"size": "1"
}
或
{
"type": "Rectangle",
"width": 1,
"length": 2
}
我的 .kt class 是这样定义的。我写了一个自定义 JsonDeserializer
但它似乎不起作用,因为 jp.readValueAs(Square::class.java)
返回 null。
@JsonDeserialize(using = Shape.Deserializer::class)
sealed class Shape {
enum class Type {
Rectangle,
Square
}
abstract val type: Type
data class Square(
val size: Int
) : Shape() {
override val type: Type = Type.Square
}
data class Rectangle(
val width: Int,
val length: Int
) : Shape() {
override val type: Type = Type.Rectangle
}
class Deserializer: JsonDeserializer<Shape>() {
override fun deserialize(jp: JsonParser, ctxt: DeserializationContext?): Shape {
var node = jp.readValueAsTree<JsonNode>()
return when(node.get("type").asText()) {
Type.Square.name ->
jp.readValueAs(Square::class.java)
Type.Rectangle.name ->
jp.readValueAs(Rectangle::class.java)
else -> throw JsonMappingException("")
}
}
}
}
我做错了什么?
干杯
回答我自己的问题:我认为可以使用 Shape
class 上的注释打开 type
属性,如下所示
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes(
value = [
JsonSubTypes.Type(value = Shape.Square::class, name = "Square"),
JsonSubTypes.Type(value = Shape.Rectangle::class, name = "Rectangle")
]
)
sealed class Shape {
enum class Type {
Rectangle,
Square
}
abstract val type: Type
data class Square(
val size: Int
) : Shape() {
override val type: Type = Type.Square
}
data class Rectangle(
val width: Int,
val length: Int
) : Shape() {
override val type: Type = Type.Rectangle
}
}