Kotlin Jackson从JSON生成对象

请帮忙! 我试图从杰克逊kotlin模块的JSON生成对象。 这里是json源码:

{ "name": "row", "type": "layout", "subviews": [{ "type": "horizontal", "subviews": [{ "type": "image", "icon": "ic_no_photo", "styles": { "view": { "gravity": "center" } } }, { "type": "vertical", "subviews": [{ "type": "text", "fields": { "text": "Some text 1" } }, { "type": "text", "fields": { "text": "Some text 2" } }] }, { "type": "vertical", "subviews": [{ "type": "text", "fields": { "text": "Some text 3" } }, { "type": "text", "fields": { "text": "Some text 4" } }] }, { "type": "vertical", "subviews": [{ "type": "image", "icon": "ic_no_photo" }, { "type": "text", "fields": { "text": "Some text 5" } }] }] }] } 

我正在尝试生成Skeleton类的实例。

 data class Skeleton (val type : String, val name: String, val icon: String, val fields: List<Field>, val styles: Map<String, Map<String, Any>>, val subviews : List<Skeleton>) data class Field (val type: String, val value: Any) 

正如你所看到的,Skeleton对象可以有其他的Skeleton对象(这些对象也可以有其他的Skeleton对象),Skeleton也可以有Field对象列表

 val mapper = jacksonObjectMapper() val skeleton: Skeleton = mapper.readValue(File(file)) 

此代码以异常结束:

 com.fasterxml.jackson.databind.JsonMappingException: Instantiation of [simple type, class com.uibuilder.controllers.parser.Skeleton] value failed (java.lang.IllegalArgumentException): Parameter specified as non-null is null: method com.uibuilder.controllers.parser.Skeleton.<init>, parameter name at [Source: docs\layout.txt; line: 14, column: 3] (through reference chain: com.uibuilder.controllers.parser.Skeleton["subviews"]->java.util.ArrayList[0]->com.uibuilder.controllers.parser.Skeleton["subviews"]->java.util.ArrayList[0]) 

我发现有几个关于您的映射的问题可以防止Jackson从JSON中读取值:

  • Skeleton类有非空的构造函数参数(例如, val type: String ,而不是String? ),如果这些参数的值在JSON中缺少,Jackson将null传递给它们。 这是你提到的异常的原因:

    指定为非null的参数为null:method com.uibuilder.controllers.parser.Skeleton.<init> ,参数name

    为了避免这种情况,您应该将可能缺失值的参数标记为空(您的情况下的所有参数):

     data class Skeleton(val type: String?, val name: String?, val icon: String?, val fields: List<Field>?, val styles: Map<String, Map<String, Any>>?, val subviews : List<Skeleton>?) 
  • Skeleton中的fields具有List<Field>类型,但是在JSON中,它由单个对象表示,而不是由数组表示。 解决方法是将fields参数类型更改为Field?

     data class Skeleton(... val fields: Field?, ...) 
  • 另外,代码中的Field类与JSON中的对象不匹配:

     "fields": { "text": "Some text 1" } 

    您也应该更改Field类,以便它具有text属性:

     data class Field(val text: String) 

在我做了我列出的更改之后,Jackson可以成功读取相关的JSON。


另请参阅: Kotlin参考中的“Null安全性” 。