3
votes

I'd like to register the Kotlin-Module with Jackson in a Quarkus application so Jackson can deserialize JSON into data classes without needing a NoArgsConstructor. What is the best way to do this?

Update after comment

The application is a REST service written in Kotlin. At the API level we use View classes (e.g. PersonView or PersonWriteView) to abstract from the models and entities on the service resp. persistence layer. To reduce overhead while still getting nice and meaningful equals() and hashcode() functions we use data classes for this.

In the vanilla settings Jackson is not able to directly deserialize into data classes because it needs an empty constructor. This can be monkey patched by applying the no-arg compiler plugin and add an annotation e.g. @NoArgConstructor similar to what Lombok offers. But of course this way we have to annotate each data class in the API which is error prone.

A better solution for this is to include com.fasterxml.jackson.module:jackson-module-kotlin which gets you the marvelous KotlinModule. After this mapper.treeToValue() can directly create data class instances without the need for an empty constructor. For this to work we have to register the module with the ObjectMapper e.g. via ObjectMapper().findAndRegisterModules(). All I want to know is how to configure the ObjectMapper which is used by Resteasy to unmarshal the JSON to objects.

2
Could you give a few more details of what your application looks like?geoand
@geoand I extended the question.Christoph Grimmer-Dietrich
Forgive my ignorance, but I am pretty sure that JSON-B is used by default in Quarkus instead of Jackson, which is why I am asking how you have things setup.geoand
Hmm... maybe I'm the ignorant one. The quarkus-bom contains dep management for jackson so I was assuming that it uses jackson to provide the binding. If this is not the case (which is totally possible) my question might rather be: How to unmarshal/deserialize/bind/duh JSON to Kotlin data classes :-DChristoph Grimmer-Dietrich
I think Jackson is used for XML, but again I am not sure. Not sure about how JSON-B would be used for handling Kotlin Data Classes, definitely something to look into :)geoand

2 Answers

1
votes

You can try to add @JsonbCreator annotation to the request model classes. So in this case JSON-B will try to use the constructor to create your objects instead of the no-args / reflection

For example:

data class MyRequest @JsonbCreator constructor(
    @JsonbProperty("propertyOne") val propertyOne: String,
    @JsonbProperty("propertyTwo") val propertyTwo: : String
)
0
votes

According to the documentation, you have to register an implementation of the (quarkus-specific) interface ObjectMapperCustomizer.

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import io.quarkus.jackson.ObjectMapperCustomizer
import javax.inject.Singleton

@Singleton
class AddKotlinModuleCustomizer : ObjectMapperCustomizer {

    override fun customize(objectMapper: ObjectMapper) {
        objectMapper.registerModule(KotlinModule())
    }
}

And of course add the kotlin module as dependency in the pom

    <dependency>
      <groupId>com.fasterxml.jackson.module</groupId>
      <artifactId>jackson-module-kotlin</artifactId>
      <version>2.10.2</version>
    </dependency>