Nat*_*ein 3 json jackson kotlin
请帮忙!我正在尝试使用jackson 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"
}
}]
}]
}]
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试生成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)
Run Code Online (Sandbox Code Playgroud)
如您所见,Skeleton对象可以在其中包含其他Skeleton对象(并且这些对象也可以包含其他Skeleton对象),Skeleton也可以具有List of Field对象
val mapper = jacksonObjectMapper()
val skeleton: Skeleton = mapper.readValue(File(file))
Run Code Online (Sandbox Code Playgroud)
此代码以例外结束:
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])
Run Code Online (Sandbox Code Playgroud)
我发现有几个关于映射的问题阻止了Jackson从JSON中读取值:
Skeletonclass具有非null构造函数参数(例如val type: String,不是String?),null如果JSON中缺少这些参数的值,Jackson会传递给它们.这就是导致您提到的异常的原因:
指定为非null的
com.uibuilder.controllers.parser.Skeleton.<init>参数为null:method ,parametername
为避免这种情况,您应该将可能包含值的参数标记为可为空(您的案例中的所有参数):
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>?)
Run Code Online (Sandbox Code Playgroud)fieldsin Skeletonhas type List<Field>,但在JSON中它由单个对象表示,而不是由数组表示.修复方法是将fields参数类型更改为Field?:
data class Skeleton(...
val fields: Field?,
...)
Run Code Online (Sandbox Code Playgroud)此外,Field代码中的类与JSON中的对象不匹配:
"fields": {
"text": "Some text 1"
}
Run Code Online (Sandbox Code Playgroud)
您也应该更改Field类,以便它具有text属性:
data class Field(val text: String)
Run Code Online (Sandbox Code Playgroud)在我列出的更改后,杰克逊可以成功阅读有问题的JSON.
另见: Kotlin参考文献中的"Null Safety".