John
John

Reputation: 1601

How to deserialize a complex JSON

I am new in Jackson and I need to deserialize JSON looks like the following:

{
  "companies": [{
    "id": "some_id",
    "type": "sale",
    "name": "Company1",
    "attributes": {
      "countPeople": 300,
      "salary": 3000
    }
  }, 
  {
    "id": "new_id",
    "type": "IT",
    "name": "Company2",
    "attributes": {
      "countPeople": 100,
      "salary": 5000,
      "city": "New York",
      ...
    }
  }]
}

I want to deserialize it to the DTO's looks like the following:

public class Companies {
    @JsonProperty("companies")
    public List<Company> companiesList;
}

public class Company {
    public String id;
    public String type;
    public String name;
    public Attributes attributes;
    
    @JsonCreator
    public Company(@JsonProperty("id") String id,
                   @JsonProperty("type") String type,
                   @JSonProperty("name") String name,
                   @JsonProperty("attributes") Attributes attributes
    ) {
        ...
    }
}

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type"
)
@JsonSubTypes({
        @JsonSubTypes.Type(name = "IT", value = ItAttributes.class)
        ...
})
public abstract Attributes {
    public int countPeople;
    ...
}

public class ItAttributes extends Attributes {
   ...
}

and when I was trying to deserialize the JSON

public class Main {
    public static void main(String... args) {
        ObjectMapper mapper = new ObjectMapper();
        Companies comp = mapper.readValue(json, Companies.class);
    }
}

I was getting an exception:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.example.dto.Attributes]: missing type id property 'type' (for POJO property 'attributes')

Obviously the Jackson doesn't see the type property, but I don't understand why.
How can I fix this issue?

Upvotes: 2

Views: 466

Answers (1)

Jo&#227;o Dias
Jo&#227;o Dias

Reputation: 17460

You actually need to use @JsonTypeInfo and @JsonSubTypes in an abstract Company as follows:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type"
)
@JsonSubTypes({
        @JsonSubTypes.Type(name = "IT", value = ItCompany.class)
        ...
})
public abstract Company {
    public String id;
    public String type;
    public String name;
}

Then you would have the concrete Company implementations:

public class ItCompany {
    public ItAttributes attributes;
}

// Other Company types

And your Attributes class would be as follows:

public abstract Attributes {
    public int countPeople;
    ...
}

public class ItAttributes extends Attributes {
   ...
}

Upvotes: 1

Related Questions