Jackson Converter for Retrofit in Kotlin

Viewed 54

Hello awesome community.

I ended up here after looking all over the places (here & others) about something that is supposed to be simple. More precisely, I am replacing GSON library with Jackson for some reasons.

Basically, what bugs me the most, is that my Jackson Converter seems to be ignored by Retrofit or something.

What I tried :

private val retrofit: Retrofit by lazy {
    Retrofit.Builder()
        .addConverterFactory(
            JacksonConverterFactory.create(jackson)
        )
        .baseUrl(BASE_URL)
        .client(httpClient)
        .build()
}

where jackson is also part of this ApiClient that I am writing

private val jackson: ObjectMapper by lazy {
    ObjectMapper()
        .registerModule(jacksonKotlinModule)
        .setDateFormat(
            SimpleDateFormat(
                "yyyy-MM-dd",
                Locale.getDefault()
            )
        )
}

and, of course jacksonKotlinModule

private val jacksonKotlinModule: KotlinModule by lazy {
    KotlinModule.Builder()
        .configure(KotlinFeature.StrictNullChecks, true)
        .build()
}

All of this in my attempt to get an error when Kotlin non-null fields of a POJO receives a null value from the response of an end-point.

On top of this, I tried the way found in every tutorials about Jackson & Kotlin which is just using jacksonObjectMapper() method available in com.fasterxml.jackson.module.kotlin

Why am I saying that seems to be ignored is because 2 reasons, neither I get any errors or warning or even crashes when I get null response for a non-null Object, neither any Date field isn't formatted as per the DateFormatter that I provided.

It does feel like I might have missed something along the way.. What could I do this in other ways? Oh, I've also tried @JsonFormat(pattern = "yyyy-MM-dd") on a specific field, without success

Later edit: Looks like after more investigations, retrofit does not completely ignore the date format I am providing, but it adapts it somehow. For example "date":"2022-08-24T13:23:10Z" and with SimpleDateFormat("yyyy-MM-dd") it parses the date for year, month, day but also adds 00 for others.. Output is: Wed Aug 24 00:00:00 GTM+03:00 2022

1 Answers

Have you added @JsonProperty annotation before all your properties in classes that you are parsing JSON to? I think that you might be missing it and that's why it doesn't work.

When you are using OkHttp directly you can specify to use jacksonObjectMapper() which uses jackson kotlin module. You can't do that when building Retrofit object as addConverterFactory() method takes Converter.Factory type and jacksonObjectMapper() returns ObjectMapper, not a factory. That's why you have to add @JsonProperty before every field.

I think it would be quite simple to create your own class that extends Converter.Factory but returns ObjectMapper with kotlin module added.

Related