请帮忙!我正在尝试使用jackson kotlin模块从JSON生成对象。这是json来源:
Please help! I'm trying to generate object from JSON with jackson kotlin module. Here is json source:
{ "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类的实例。
I'm trying to generate instance of Skeleton class.
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对象列表
As you can see, Skeleton object can have other Skeleton objects inside (and these objects can have other Skeleton objects inside too), also Skeleton can have List of Field objects
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])推荐答案
我发现有几个关于你的映射的问题阻止杰克逊从JSON读取值:
There are several issues I found about your mapping that prevent Jackson from reading the value from JSON:
-
Skeleton 类具有非null构造函数参数(例如 val type:String ,而不是 String? ),如果JSON中缺少这些参数的值,Jackson会将 null 传递给他们。这就是导致你提到的异常的原因:
Skeleton class has not-null constructor parameters (e.g. val type: String, not String?), and Jackson passes null to them if the value for those parameters is missing in JSON. This is what causes the exception you mentioned:
指定为非null的参数为null:method com.uibuilder .controllers.parser.Skeleton。< init> ,参数 name
为避免这种情况,您应该将可能包含值的参数标记为可为空(在您的情况下为所有参数):
To avoid it, you should mark the parameters that might might have values missing as nullable (all of the parameters in your case):
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>?)
字段 in Skeleton 的类型 List< Field> ,但在JSON中,它由单个对象表示,而不是由数组表示。修复方法是将字段参数类型更改为字段?:
fields in Skeleton has type List<Field>, but in JSON it's represented by a single object, not by an array. The fix would be to change the fields parameter type to Field?:
data class Skeleton(... val fields: Field?, ...)
此外,代码中的 Field 类与JSON中的对象不匹配:
Also, Field class in your code doesn't match the objects in JSON:
"fields": { "text": "Some text 1" }您还应该更改 Field 类,以便它 text property:
You should change Field class as well, so that it has text property:
data class Field(val text: String)
在我列出的变更后,杰克逊可以成功阅读有问题的JSON。
After I made the changes I listed, Jackson could successfully read the JSON in question.
另见: Kulllin参考中的Null Safety。
更多推荐
来自JSON的Kotlin Jackson生成对象
发布评论