Пустой результат из rest api

Я хочу создать службу для заполнения раскрывающегося списка из базы данных. Я пробовал это:

Класс торговца:

export class Merchant {
  constructor(
    public id: string,
    public name: string,
    public state_raw: string,
    public users: string,
  ) {}
}

Торговая служба:

 getList(): Observable<Merchant> {
    return this.http.get<Merchant>(environment.api.urls.merchants.base, {});
  }

SQL-запрос:

@Override
    public Iterable<Merchants> findAll() {
        String hql = "select e from " + Merchants.class.getName() + " e";
        TypedQuery<Merchants> query = entityManager.createQuery(hql, Merchants.class);
        List<Merchants> merchants = query.getResultList();
        return merchants;
    }

Рабочий пример:

    @GetMapping("/list")
public Iterable<Merchants> getMerchantsList() {
    return merchantRepository
            .findAll();
}

Я пробовал это:

@GetMapping("/list")
public ResponseEntity<?> getMerchantsList() {
    return StreamSupport.stream(merchantRepository.findAll().spliterator(), false)
            .map(mapper::toDTO)
            .map(ResponseEntity::ok)
            .findFirst()
            .orElseGet(() -> notFound().build());
}

Я хочу использовать картограф, прежде чем отправлять ответ. В настоящее время список в Angular пуст. Наверное, мне стоит вернуть Iterable<Merchants>, а не ResponseEntity<MerchantDTO>?

Я использую Java 10.

Ваша остальная услуга вернет список торговцев. Ваш сервис angular возвращает Observable, излучающий одного продавца. Это не совпадает. Вам нужен массив для заполнения dropdon, не так ли?

JB Nizet 03.11.2018 10:43

Да, как я могу это реализовать?

Peter Penzov 03.11.2018 10:44

Ну, изменив тип на Array <Merchant>. Кроме того, почему ваш метод getMerchantsList () возвращает void вместо ... списка продавцов? Почему он использует findFirst ()? Вы хотите вернуть всех торговцев, а не только первого. Вам нужно собрать (Collectors.toList ()), а не findFirst (). OrElseGet (). И вы хотите вернуть этот список, а не игнорировать его.

JB Nizet 03.11.2018 10:46

Виноват. Извините. Пост обновлен.

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

Ответы 1

Ответ принят как подходящий

Есть несколько проблем с обеих сторон. Начнем со стороны сервера. Вы хотите вернуть список продавцов, чтобы заполнить раскрывающийся список список, поэтому вы правильно назвали свой метод getMerchantsСписок (). Но вместо того, чтобы возвращать список, как указывает его имя, он возвращает void. void ничего, нада, отсюда и пустой ответ.

Поэтому вам нужно вернуть List<Merchant> или, если вы действительно хотите (но здесь это не нужно, поскольку вы не хотите устанавливать ничего, кроме тела ответа), ResponseEntity<List<Merchant>>. Вызов findFirst() контрпродуктивен. Вам не нужен первый продавец в списке. Вам нужен весь список:

@GetMapping("/list")
public List<MerchantDTO> getMerchantsList() {
    return StreamSupport.stream(merchantRepository.findAll().spliterator(), false)
            .map(mapper::toDTO)
            .collect(Collectors.toList());
}

или

@GetMapping("/list")
public ResponseEntity<List<MerchantDTO>> getMerchantsList() {
    List<MerchantDTO> list = StreamSupport.stream(merchantRepository.findAll().spliterator(), false)
            .map(mapper::toDTO)
            .collect(Collectors.toList());
    return ResponseEntity.ok(list);
}

Обратите внимание, что код был бы проще, если бы ваш метод findAll () возвращал List вместо Iterable. Вы можете просто использовать findAll().stream() для получения потока.

На стороне клиента вы делаете ту же ошибку. Вы хотите, чтобы тело ответа было множество продавцов, чтобы заполнить раскрывающийся список список. Но вы используете Observable<Merchant>. Вам нужен Observable<Array<Merchant>>. А передача пустого объекта параметров в get() бесполезна:

getList(): Observable<Array<Merchant>> {
  return this.http.get<Array<Merchant>>(environment.api.urls.merchants.base);
}

Наконец, вы обманываете себя, создавая класс. HttpClient никогда не создаст экземпляр вашего класса. Он не знает об этом и просто анализирует JSON, который он получает, на простые старые объекты JavaScript. Поэтому вам действительно следует определять интерфейс, а не класс:

export interface Merchant {
  id: string;
  name: string;
  state_raw: string;
  users: string;
}

Вам также действительно следует использовать Spring-data-jpa. Это значительно упростило бы ваши репозитории.

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