Вызов Java Spring Rest для получения подкласса с использованием суперкласса

Я пытаюсь сохранить несколько похожих документов в одном и том же хранилище документов (MongoDB), то есть все классы, расширяющие Foo, хранятся в коллекции Foo.

У меня есть конечная точка отдыха, называемая findById, которая возвращает тип Optional, например. /foo/{идентификатор}.

Когда я отлаживаю это, он возвращает класс Bar (который расширяет Foo

Однако, когда я вызываю это из клиентского приложения Java.

Фу Класс

    @Data
    @Document(collection = "foo")
    public abstract class Foo {
        @Id
        private int id;

        public Foo(){}
        public Foo(int id){
            this.id = id;
        }

Бар Класс

    @Document(collection = "foo")
    @Data
    public class Bar extends Foo{
        private String text;

        @PersistenceConstructor
        public EnterValue(int id, String text){
            super(id);
            this.text = text;
        }

        @Override
        public int getId() {
            return super.getId();
        }

        @Override
        public int setId(UUID id) {
            super.setId(id);
        }

        public String getText(){
            return this.text;
        }

        public void setText(String text) {
            this.text = text;
        }

Код клиента:

    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<>(headers);
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<Foo> response = restTemplate.exchange("http://localhost:8080/foo/123",HttpMethod.GET,entity,Foo.class);

Я получаю сообщение об ошибке при извлечении ответа для типа [класс Foo] и типа содержимого [application/json;charset=UTF-8].

пожалуйста, опубликуйте ошибку и контроллер тоже.

davidxxx 20.06.2019 21:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
838
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  • тип, который вы помещаете в алмазный оператор ResponseEntity, не может быть абстрактным;
  • он должен реализовать Serializable.

public class Bar extends Foo implements Serializable { ... } ... ResponseEntity<Bar> response = restTemplate.exchange("http://localhost:8080/foo/123", HttpMethod.GET, entity, Bar.class);

Есть ли другой способ сделать это? У меня есть где-то еще в коде объекты списка, которые расширяют Foo с помощью Order. и поскольку он извлекается из БД, это может быть любой класс, который расширяет Foo.

Andrew Evans 21.06.2019 14:50

Я бы сделал это ResponseEntity<String> для получения необработанного тела, а затем десериализовал его в нужный тип (используя установленные вами критерии). ResponseEntity<Bar> автоматически делает то же самое для вас, то есть десериализует строку json в Bar. Класс, который не является сериализуемым, не может быть десериализован; и абстрактный класс не может быть создан и, следовательно, не может быть десериализован.

Ivan Skalauh 21.06.2019 18:16

Другие вопросы по теме