简体   繁体   中英

SpringBoot: Request body with inheritance

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.

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.

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".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM