Search code examples
javajsonjacksonmappingdto

How to identify different types automatically using Jackson mapper


I have a simple situation. I have a main DTO class with the following fields: AnimalDTO

public class AnimalDTO {
    @JsonCreator
    public AnimalDTODTO(@JsonProperty("error") boolean error,
                                       @JsonProperty("errorMessage") String errorMessage,
                                       @JsonProperty("cat") CatDTO cat,
                                       @JsonProperty("dog") DogDTO dog) {
        this.error = error;
        this.errorMessage = errorMessage;
        this.cat = cat;
        this.dog = dog;
    }

    private boolean error;
    private String errorMessage;
    private CatDTO cat;
    private DogDTO dog;
}

CatDTO:

public class CatDTO {
    @JsonCreator
    public CatDTO(@JsonProperty("catNumber") String catNumber,
                  @JsonProperty("catState") String catState) {
        this.catNumber = catNumber;
        this.catState = catState;
    }

    private String catNumber;
    private String catState;
}

DogDTO:

public class DogDTO {
    @JsonCreator
    public DogDTO(@JsonProperty("dogNumber") String dogNumber,
                  @JsonProperty("dogState") String dogState
                  @JsonProperty("dogColor") String dogColor
                  @JsonProperty("dogBalance") BigDecimal dogBalance) {
        this.dogNumber = dogNumber;
        this.dogState = dogState;
        this.dogColor = dogColor;
        this.dogBalance = dogBalance;
    }

    private String dogNumber;
    private String dogState;
    private String dogColor;
    private BigDecimal dogBalance;

}

and from external API I have responses (and I can't change it) for dog like:

{
   "dogNumber": "23",
   "dogState": "good",
   "dogColor": "pink",
   "dogBalance": 5
}

and for Cat:

{
   "catNumber": "1",
   "catState": "good"
}

And I want to use Jackson mapper like this: objectMapper.readValue(stringJson, AnimalDTO.class);

I was thinking to add in AnimalDTO:

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME, 
  include = JsonTypeInfo.As.PROPERTY, 
  property = "type")
@JsonSubTypes({ 
  @Type(value = CatDTO.class, name = "cat"), 
  @Type(value = DogDTO.class, name = "dog") 
})

but it's not working.

How to handle my case in best way?


Solution

  • Your code will work just fine (without any @JsonTypeInfo or @JsonSubTypes annotations) if the JSON that you get from the external API is as follows:

    {
      "dog": {
        "dogNumber": "23",
        "dogState": "good",
        "dogColor": "pink",
        "dogBalance": 5
      },
      "cat": {
        "catNumber": "1",
        "catState": "good"
      }
    }
    

    If this does not look similar to the JSON you receive then you need to add it to your answer so that we can help you further.