Как вернуть N1qlQueryResult в качестве ответа REST API для Couchbase databse?

#java #json #spring #nosql #couchbase

#java #json #spring #nosql #couchbase

Вопрос:

Я хочу вернуть N1qlQueryResult в качестве ответа моего REST API . Ниже приведен код:

 @RequestMapping(value = "/test", method = RequestMethod.GET)
public @ResponseBody ResponseEntity<?> get() {
    List<N1qlQueryRow> result = null;
    try {
        Cluster cluster = CouchbaseCluster.create("localhost");
        Bucket bucket = cluster.openBucket("myBucket", "xyz");
        bucket.bucketManager().createN1qlPrimaryIndex(true, false);
        N1qlQueryResult queryResult = bucket.query(N1qlQuery.simple("select * FROM myBucket"));
        queryResult.forEach(System.out::println);
        result = queryResult.allRows();
    } catch (final Exception exception) {
        exception.printStackTrace();
    }
    return ResponseEntity.ok(result); 
}
  

Я получаю сообщение об ошибке:

Не удалось записать содержимое: не найден сериализатор для класса com.couchbase.client.java.query.DefaultN1qlQueryRow и не обнаружено свойств для создания BeanSerializer (чтобы избежать исключения, отключите SerializationFeature.СБОЙ_ON_EMPTY_BEANS) (через цепочку ссылок: java.util.ArrayList[0]); вложенным исключением является com.fasterxml.jackson.databind.Исключение JsonMappingException: не найден сериализатор для класса com.couchbase.client.java.query.DefaultN1qlQueryRow и не обнаружено свойств для создания BeanSerializer (чтобы избежать исключения, отключите SerializationFeature.СБОЙ_ON_EMPTY_BEANS) (через цепочку ссылок: java.util.ArrayList[0])

Каково решение? Я хочу вернуть ответ как JSON .

Ответ №1:

ObjectMapper по умолчанию происходит сбой, когда используется компонент empty . Мы можем отключить это, как показано ниже:

 ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
  

но в вашем случае это не решает проблему, потому что результат в любом случае будет пустым. Нет хорошей идеи возвращать type -ы, которые не представляют POJO себя. N1qlQueryResult и DefaultAsyncN1qlQueryRow не имеют классических getters и Jackson по умолчанию не распознают одинаковые методы value() . Я предлагаю создать Map<String, Object> и собрать требуемый вывод и включить необходимые свойства вручную:

 Map<String, Object> n1QlResult = new HashMap<>();
n1QlResult.put("status", result.status());
// other ...
n1QlResult.put("rows", result.allRows()
        .stream()
        .map(i -> i.value().toMap())
        .collect(Collectors.toList()));
  

и, наконец, вернуть:

 return ResponseEntity.ok(n1QlResult);
  

Конечно, когда у вас есть много подобных методов, вы можете написать common layer, который преобразует объекты такого типа в Map или написать пользовательский сериализатор и настроить ObjectMapper пользователя по Spring контейнеру.

ОТРЕДАКТИРУЙТЕ
, если вы хотите возвращать только строки return:

 result.allRows()
        .stream()
        .map(i -> i.value().toMap())
        .collect(Collectors.toList())
  

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

1. Но он возвращает имя корзины с каждым элементом, я уже написал подобный тип кода. То, что я хочу, это простой json, например, если строки в базе данных похожи: 1-я строка: {«key1″:»value1»}, 2-я строка: {«key2»: «value2»}. Выходные данные должны быть такими: [{«key1″:»value1»},{«key2″:»value2»}].

2. @iAmLearning, смотрите мое обновление. Просто преобразуйте N1qlQueryResult в список объектов, используя Stream API или foreach в список Map -ов.