Reputation: 3941
I have following classes
public class Car {
private String make;
private String model;
private TransmissionType transmissionType; // Manual/Automatic
private Transmission transmission;
}
public class Transmission {
}
public class AutomaticTransmission {
public Technology technology; // DCT/CVT/AMT
}
public class ManualTransmission {
public int numGears;
}
In this example, when the payload passed could be
{
"make": "Toyota",
"model": "Iris",
"transmissionType": "Automatic",
"transmission" {
"technology": "DCT"
}
}
or it could be
{
"make": "Merc",
"model": "C",
"transmissionType": "Manual",
"transmission" {
"numGears": 5
}
}
When this is passed to controller as body, it should be able to create respective class. How do I achieve this.
I tried using JsonTypeInfo
and JsonSubTypes
as shown in this answer but it necessitates me to move transmissionType
within Transmission
class, which is not the case for me.
Upvotes: 0
Views: 2271
Reputation: 3941
With help of @chrylis's pointers.
I wrote the code as below
class Car {
...
private TransmissionType transmissionType;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "transmissionType")
private Transmission transmission;
}
@JsonSubTypes({
@JsonSubTypes.Type(value = AutomaticTransmission.class, name = "AUTOMATIC"),
@JsonSubTypes.Type(value = ManualTransmission.class, name = "MANUAL")
})
public abstract class Transmission {
}
Few gotchas I found, mentioning FYI.
If you put JsonSubTypes
on the field in Car
class, Swagger documentation won't work. If you put, @JsonTypeInfo
on the class Transmission
then SpringBoot won't recognise the field "transmissionType".
Upvotes: 0
Reputation: 77167
You're looking for @JsonTypeInfo(include = As.EXTERNAL_PROPERTY) Transmission transmission
. This tells Jackson to look for the property that defines the type in the containing object.
That said, if you have any opportunity of changing your JSON shape, you should avoid "externally tagged types" like this and put the type property into the object.
Upvotes: 1