I have a controller with @RequestBody
@PostMapping("/")
public String doSomething(@RequestBody ??? foo)
foo can be 2 different objects. Foobject or Barobject. I don't know what will the object sent. These objects are totally different without any kind of common fields where I could use @JsonTypeInfo and @JsonSubTypes
I can workaround this and use ObjectMapper to try to map it to on of the 2 classes:
@RequestBody Object json
...
ObjectMapper objectMapper = new ObjectMapper();
try {
Foobject obj = objectMapper.convertValue(json, Foobject.class);
}
catch (IllegalArgumentException ei){
Barobject obj = objectMapper.convertValue(json, Barobject.class);
}
Is there a proper way to do this? Or better said, alternatives? I know this goes against REST API development, because this should be another method, each with its own object.
CodePudding user response:
You can choose to use, Object, class like this and then take advantage of the function
mapper.readValue(jsonStr, Fooobject.class);
method throws JsonMappingException
@PostMapping("/")
public String doSomething(@RequestBody Object foo) {...}
boolean isA(String json, Class expected) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(json, expected);
return true;
} catch (JsonMappingException e) {
e.printStackTrace();
return false;
}
}
Well you said that "I don't know what will the object sent", so you can only do trial and error.
Else modify your request to involve a "Type" or something (I would do this by Making a parent class with only "type" member of ObjectType type, and child classes extending that parent class.
enum ObjectType {FOO, BAR}
Method 1: Use readValue() function of jackson Method 2: Do a string search (just to make it faster) something unique non-nullable field about any of the object. Method 3: Modify the request.
CodePudding user response:
Managed to do it with Jackson. Create parent class, and both objects extend from parent. On the parent added:
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(Foobject.class),
@JsonSubTypes.Type(Barobject.class),,
})
This works pretty well, and I guess is a clean solution. Also, has the advantage to be done on a Spring layer, where other validations defined on fields of the classes will occur.
That wasn't the case with other solutions.