Как указать конечную точку API REST, принимающего список типов с использованием супертипа?

#json #spring-boot #rest #request

Вопрос:

Я намерен указать конечную точку REST в приложении Spring Boot, которое принимает список объектов ( List<? extends SuperObject> ). SuperObject является абстрактным базовым классом. Списки, отправленные в теле запроса HttpRequest, содержат экземпляры SuperObject подклассов / дочерних классов ( SubType1OfSuperObject и SubType2OfSuperObject ).

В настоящее время я попробовал это:

 @PostMapping(path = "store", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public String store(@RequestBody List<? extends SuperObject> oject, @RequestParam Technology technology) {
    theService.saveObjectsByTechnology(objects, technology);
    return "Perfect!";
}
 

Я попытался отправить список объектов подтипа с помощью почтальона:

 {
  "subtype1OfSuperObjects": [
    {
      "prop1": 4,
      "prop2": "foo",
      "prop3": "xxx"
    },
    {
      "prop1": 7,
      "prop2": "Bar",
      "prop3": "zzz"
    }
  ]
}
 

В результате получается

 {
    "timestamp": "2021-08-18T12:24:55.797 00:00",
    "status": 400,
    "error": "Bad Request",
    "path": "/admin/error/store"
}
 

Класс суперобъектов:

 @Data
@SuperBuilder
@NoArgsConstructor
@Validated
public abstract class SuperObject  {

    private Integer prop1;

    private String prop2;

}
 

Класс SubType1OfSuperObject:

 @Data
@SuperBuilder
@NoArgsConstructor
@Validated
public class SubType1OfSuperObject extends SuperObject  {

    private String prop3;

}
 

Класс SubType1OfSuperObject:

 @Data
@SuperBuilder
@NoArgsConstructor
@Validated
public class SubType2OfSuperObject extends SuperObject  {

    private String prop4;

}
 

Как я могу этого достичь? Классы the supertype и the subtypes , конечно, реализованы.

API REST доступен, так как я могу вызвать другую конечную точку (GET) (например, для перечисления всех подтипов).

Комментарии:

1. По словам Филдинга, у REST нет конечных точек, а есть только ресурсы. Далее сервер должен научить клиента тому, что отправлять, если сервер ожидает ввода с помощью представлений, подобных формам, т. Е. HTML поддерживает формы, которые определяют, куда отправлять запрос, какую операцию использовать, тип носителя, для которого создается представление, и соответствующие элементы, которые сервер ожидает в качестве входных данных. Все остальное-это не ОТДЫХ, а чистый RPC. Набор функций JSON не включает такие возможности, однако в схеме JSON вы можете использовать { ..., "type": { "$ref": "supertype"}, ...} для определения такого отношения.

Ответ №1:

Если я правильно понимаю, у вас есть список данных для отправки? если это так, у вас может быть что-то вроде приведенного ниже:

В вашем контроллере

 @PostMapping("/")
@ResponseBody
public String save(@RequestBody List<Data> data){
    System.out.println(data);
    return "good";
}
 

И вы определяете свои данные pojo следующим образом

 class Data{
    private List<SubData> subtype1OfSuperObjects;
    //getters, setters and toString
}

class SubData{
    private int prop1;
    private String prop2;
    // getters, setters and toString
}
 

Вот результат по sysout

 [Data{subtype1OfSuperObjects=[SubData{prop1=4, prop2='foo'}, SubData{prop1=7, prop2='Bar'}]}]