0

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.

1

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

That worked. Thanks you. I have added answer with full code so that it helps other people.
0

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

2 Comments

Thanks Ganesh & @chrylis-cautiouslyoptimistic, Really very helpful knowledge for me It is working with RequestBody. In my case, I have to upload a file along with data. I've tried the same with ModelAttribute but, It is not working. Is there any way to achieve the same with ModelAttribute too.
As per my information, you can't upload file with data unless you move everything to form fields from JSON. Better way is to upload the file separately and send the URL along with the REST request. I've worked on the cases, where files are uploaded along with fields using forms but it becomes to cumbersome. I'd suggest not to do that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.