来自JSON的Kotlin Jackson生成对象

时间:2016-10-10 13:43:03

标签: 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"
                }
            }]
        }]
    }]
}

我正在尝试生成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])

1 个答案:

答案 0 :(得分:6)

我发现有几个关于映射的问题阻止杰克逊从JSON中读取值:

  • key = "%#{search_text}%" @payment_requests = PaymentRequest.joins(:detail).where('payment_details.first_name LIKE :search OR payment_details.last_name LIKE :search', search: key) 类具有非null构造函数参数(例如Skeleton,而不是val type: String),并且如果这些参数的值,Jackson会将String?传递给它们在JSON中缺少。这就是导致你提到的例外的原因:

      

    指定为非null的参数为null:方法null,参数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>?) 中的
  • fields类型为Skeleton,但在JSON中,它由单个对象表示,而不是由数组表示。修复方法是将List<Field>参数类型更改为fields

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

    Field

    您也应该更改"fields": { "text": "Some text 1" } 类,以便它具有Field属性:

    text

在我列出的更改后,杰克逊可以成功阅读有问题的JSON。

另请参阅: "Null Safety" in Kotlin reference