JSON Kotlin Jackson Generation Objects

Please, help! I am trying to create an object from JSON with the jackson kotlin module. Here is the 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" } }] }] }] } 

I am trying to create an instance of the 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) 

As you can see, a Skeleton object can have other Skeleton objects inside (and these objects can have other Skeleton objects inside), also Skeleton can have List of Field objects

 val mapper = jacksonObjectMapper() val skeleton: Skeleton = mapper.readValue(File(file)) 

This code ends with an exception:

 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
source share
1 answer

There are several issues that I found about your mapping that prevent Jackson from reading the value from JSON:

  • Skeleton class has non-null constructor parameters (for example, val type: String , not String? ), And Jackson passes them null if the value for these parameters is not in JSON. This is why you mentioned the exception:

    The parameter specified as non-empty is null: the com.uibuilder.controllers.parser.Skeleton.<init> method, the name parameter

    To avoid this, you should mark parameters that might have values ​​that are absent as nullable (all 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>?) 
  • fields in Skeleton is of type List<Field> , but in JSON it is represented by a single object, not an array. The fix would be to change the type of the fields parameter to Field? :

     data class Skeleton(... val fields: Field?, ...) 
  • Also, the Field class in your code does not match objects in JSON:

     "fields": { "text": "Some text 1" } 

    You must also change the Field class so that it has the text property:

     data class Field(val text: String) 

After I made the changes listed by me, Jackson could successfully read the JSON in question.


See also: "Null Safety" in the Kotlin help system .

+4
source

Source: https://habr.com/ru/post/1275544/


All Articles