Home > database >  @RequestBody where object can be 2 different class
@RequestBody where object can be 2 different class

Time:10-22

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.

  • Related