1
votes

When using Spring's RestTemplate to deserialize some JSON response into an object I fail to do so because I use a Kotlin data class as my object model.

This is the data class:

data class Description (
        val descriptionShort: String,
        val descriptionLong: String,
        val productGroupName: String,
        val shortDescriptionProductGroup: String,
        val descriptionProductGroupMarketing: String
)

I using these dependencies:

    dependencies {
        implementation("org.springframework.boot:spring-boot-starter-webflux")
        //others
    }

    dependencyManagement {
        imports {
            mavenBom("org.springframework.boot:spring-boot-dependencies:2.2.0.RELEASE")
            //others
        }
        dependencies {
            dependency("org.springframework.cloud:spring-cloud-stream-reactive:2.2.1.RELEASE")
            dependency("com.fasterxml.jackson.module:jackson-module-kotlin:2.10.2")
            //others

        }
    }

The error message when executing unit tests that involves the RestTemplate logic:

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.company.importer.customer.converter.ut.Description (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

2

2 Answers

3
votes

I faced a similar problem many days ago; as first step, I solved the problem as in the response by @xetra11, but I was not very happy with the idea of having default values for technical reasons only.

Finally I solved my issue simply adding the @RequestBody annotation to the controller's method parameter: my method now looks like

fun newTransaction(@RequestBody input: NewTxRequest)

NewTxRequest is defined as follows

data class NewTxRequest(val from: String, val to: String, val amount: BigDecimal)

and the serialization works fine... I hope this can help you, too!

2
votes

A friend told me a no-arg constructor is needed. This is done in Kotlin by giving every property a default value:

data class Description (
        val descriptionShort: String = "",
        val descriptionLong: String = "",
        val productGroupName: String = "",
        val shortDescriptionProductGroup: String = "",
        val descriptionProductGroupMarketing: String = ""
)