来自JSON的Kotlin Jackson生成对象 [英] Kotlin Jackson generation objects from JSON

查看:282
本文介绍了来自JSON的Kotlin Jackson生成对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请帮忙!我正在尝试使用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生成对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆