Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you make Jackson use Kotlin default params for missing values?

Tags:

I've a Kotlin data class that looks like this,

data class SomeData(    private val notInJson: String = "some default value",    private val inJson: String ) 

and a json string, I wish to deserialize into an instance of this class -

{     "inJson" : "value" } 

When I try to deserialize this data, I get an error that the parameter notInJson cannot be null. Seems like Jackson is passing a null value for it since it's missing in the json string.

Is there a way to have Jackson not pass in any value for it, so that the default specified in the class definition could be used?

--EDIT--

I do register a KotlinModule() with the mapper. Using version 2.7.8 or all jackson packages involved.

The following code -

@Test fun jackson_kotlin_module() {     val mapper = ObjectMapper().registerModule(KotlinModule())     println(         mapper.readValue("""{ "inJson" : "some value" }""",     SomeData::class.java)) } 

gives me -

com.fasterxml.jackson.databind.JsonMappingException: Instantiation of [simple  type, class SomeData] value failed (java.lang.IllegalArgumentException):  Parameter specified as non-null is null: method SomeData.<init>, parameter  notInJson at [Source: { "inJson" : "some value" }; line: 1, column: 27] 
like image 708
0cd Avatar asked Oct 28 '16 03:10

0cd


People also ask

Does Jackson need default constructor?

Jackson uses default (no argument) constructor to create object and then sets value using setters. so you only need @NoArgsConstructor and @Setter.

What does Jackson module kotlin do?

GitHub - FasterXML/jackson-module-kotlin: Module that adds support for serialization/deserialization of Kotlin (http://kotlinlang.org) classes and data classes. Module that adds support for serialization/deserialization of Kotlin (http://kotlinlang.org) classes and data classes.


1 Answers

Default params is a Kotlin feature. Jackson does not know about it hence we need to inform it somehow to be able to support it. Thankfully there's the excellent jackson-kotlin-module which let's you do:

val mapper: ObjectMapper = ObjectMapper()         .registerModule(KotlinModule()) //let Jackson know about Kotlin ... data class SomeData(     private val notInJson: String = "some default value",     private val inJson: String ) ... val data = mapper.readValue<SomeData>("""{"inJson": "sample value"}""") println(data) // -> SomeData(notInJson=some default value, inJson=sample value) 

For instructions how to use it take a look at jackson-kotlin-module Readme and pay special attention to versions of the module and Jackson itself. In order for the default parameters to work you need at least version 2.8.4 of jackson-kotlin-module

like image 67
miensol Avatar answered Sep 20 '22 21:09

miensol