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安全性” 。