How do I tell the Jackson JSON deserializer to prefer one field over another when both are present?

29 views Asked by At

I am writing code to parse JSON responses from a service where I can get two different formats that I want to map to the same kind of object. This is a simplified example of my code:

data class MyClass @JsonCreator constructor(
  @JsonProperty("name")
  @JsonAlias("title")
  val name: String
)

Here are a couple of JSON blobs that work fine with this setup:

{
  "name": "Mr. Jones"
}

{
  "title": "The Doctor"
}

However, if I have JSON that contains BOTH of these fields, the deserializer errors out:

{
  "name": "Mr. Jones",
  "title": "The Doctor"
}
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No fallback setter/field defined for creator property 'name' (through reference chain: com.example.MyClass["name"])

I assume this is because the deserializer doesn't understand which one of the two fields it should use. Is it possible to instruct it on which one it should prefer if both are present? My intent is to prefer name over title if both are present, so title should only be deserialized if name isn't present.

I am currently using Jackson 2.16.1, and have jackson-core, jackson-annotations, jackson-databind, jackson-dataformat-csv, and jackson-module-kotlin in my Maven project.

Here's the primary configuration for my ObjectMapper:

val mapper: ObjectMapper = ObjectMapper()
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    .configure(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY, false)
    .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
    .configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false)
    .configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
    .setSerializationInclusion(JsonInclude.Include.NON_NULL)
    .registerKotlinModule()

I've tried looking for alternatives to @JsonAlias (there aren't any that I found to do this), and also tried setting up alternative @JsonCreator methods. Unfortunately, in the real case, there are four fields that I'm concerned about, and I can't just write new creators for each conceivable combination of fields that might appear in the JSON.

@JsonAlias also doesn't appear to have any configuration options, and I haven't found an option in the main deserializer config for the object mapper - at least, one that I understood.

Thanks!

0

There are 0 answers