【问题标题】:How to return N1qlQueryResult as the response of REST API for Couchbase databse?如何返回 N1qlQueryResult 作为 Couchbase 数据库的 REST API 的响应?
【发布时间】:2019-08-06 08:47:05
【问题描述】:

我想返回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.FAIL_ON_EMPTY_BEANS)(通过引用链: java.util.ArrayList[0]);嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:没有序列化程序 为类 com.couchbase.client.java.query.DefaultN1qlQueryRow 找到 并且没有发现创建 BeanSerializer 的属性(以避免 异常,禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过 参考链:java.util.ArrayList[0])

解决办法是什么?我想以JSON 的形式返回响应。

【问题讨论】:

    标签: java json spring nosql couchbase


    【解决方案1】:

    ObjectMapper 默认在 bean 为 empty 时失败。我们可以像下面这样禁用它:

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

    但在您的情况下,它并不能解决问题,因为结果无论如何都是空的。返回不代表POJO 本身的type-s 不是一个好主意。 N1qlQueryResultDefaultAsyncN1qlQueryRow 没有经典的 gettersJackson 默认不识别类似 value() 的方法。我建议创建Map&lt;String, Object&gt; 并手动构建所需的输出并包含所需的属性:

    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);
    

    当然,当你有很多这样的方法时,你可以编写通用层将这些对象转换为Map,或者编写自定义序列化器并通过Spring容器配置ObjectMapper用户。

    编辑
    如果您只想返回行返回:

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

    【讨论】:

    • 但它会返回每个项目的存储桶名称,我已经编写了类似类型的代码。我想要的是简单的 json,例如,如果 db 中的行如下:第一行:{“key1”:“value1”},第二行:{“key2”:“value2”}。输出应该类似于:[{"key1":"value1"},{"key2":"value2"}]。
    • @iAmLearning,查看我的更新。只需将N1qlQueryResult 转换为对象列表,使用Stream APIforeach 转换为Map-s 列表。
    猜你喜欢
    • 2020-12-19
    • 1970-01-01
    • 2022-01-23
    • 2017-12-03
    • 2019-11-25
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多