【问题标题】:GSON polymorphic deserialization cannot deserialize `type` property using RuntimeTypeAdapterFactoryGSON 多态反序列化无法使用 RuntimeTypeAdapterFactory 反序列化 `type` 属性
【发布时间】:2020-03-22 04:51:18
【问题描述】:

我正在尝试使用 gson 类型适配器来反序列化我的 JSON。我能够使对象反序列化,但 type 属性始终返回 null。

JSON:

{
"type": "rectangle",
"x": "3",
"y": "3",
"description": "this is my battle ground",
"children": [
{
  "type": "square",
  "x": "3",
  "y": "4",
  "description": "this is my arena",
  "children": [
    {
      "type": "circle",
      "x": "0",
      "y": "0",
      "radius": "3",
      "description": "this is my inner circle"
    },
    {
      "type": "circle",
      "x": "0",
      "y": "0",
      "radius": "4",
      "description": "this is my inner circle"
    },
    {
      "type": "circle",
      "x": "0",
      "y": "0",
      "radius": "5",
      "description": "this is my inner circle"
    }
   ]
  }
 ]
}

型号:

abstract class Shape {
    abstract val type: String
    abstract val x: String
    abstract val y: String
    abstract val description: String
}

abstract class ShapeChildren : Shape() {
    abstract val children: List<Shape>
}


enum class ShapeType(val type: String) {
    SQUARE("square"),
    RECTANGLE("rectangle"),
    CIRCLE("circle")
}

data class Square(override val type: String, override val x: String, override val y: String, override val description: String, override val children: List<Shape>) : ShapeChildren()
data class Rectangle(override val type: String, override val x: String, override val y: String, override val description: String, override val children: List<Shape>) : ShapeChildren()
data class Circle(override val type: String, override val x: String, override val y: String, override val description: String, val radius: String) : Shape()

配置 GSON:

 val jsonResponse = loadFile("mock-response/shape.json")
        val adapterFactory = RuntimeTypeAdapterFactory.of(Shape::class.java)
            .registerSubtype(ShapeChildren::class.java)
            .registerSubtype(Square::class.java, "square")
            .registerSubtype(Circle::class.java, "circle")
            .registerSubtype(Rectangle::class.java, "rectangle")
        val gson = GsonBuilder()
            .registerTypeAdapterFactory(adapterFactory)
            .create()
        val shape = gson.fromJson(jsonResponse, Shape::class.java)
        print(shape)

输出:

Rectangle(type=null, x=3, y=3, description=this is my battle ground, children=[Square(type=null, x=3, y=4, description=this is my arena, children=[Circle(type=null, x=0, y=0, description=this is my inner circle, radius=3), Circle(type=null, x=0, y=0, description=this is my inner circle, radius=4), Circle(type=null, x=0, y=0, description=this is my inner circle, radius=5)])])

对于子类,type 属性始终为 null。我什至试图通过在构造函数中给它一个默认值来设置它。为什么 type 属性没有正确填充?我错过了什么?

【问题讨论】:

    标签: json kotlin gson json-deserialization runtimetypeadapterfactory


    【解决方案1】:

    只需使用RuntimeTypeAdapterFactory.of(Shape::class.java, "type", true) 而不是RuntimeTypeAdapterFactory.of(Shape::class.java)。最后一个参数是maintainType。您已将其设置为 false,在这种情况下,类型属性会在反序列化之前从 json 中删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多