How to return N1qlQueryResult as the response of REST API for Couchbase databse?

狂风中的少年 提交于 2019-12-11 11:57:37

问题


I want to return the N1qlQueryResult as a response of my REST API. Below is the code:

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

I get error message:

Could not write content: No serializer found for class com.couchbase.client.java.query.DefaultN1qlQueryRow and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class com.couchbase.client.java.query.DefaultN1qlQueryRow and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0])

What is the solution? I want to return response as JSON.


回答1:


ObjectMapper by default fails when bean is empty. We can disable this like below:

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

but in your case it does not solve a problem because result will be empty anyway. There is no good idea to return type-s which do not represent POJO itself. N1qlQueryResult and DefaultAsyncN1qlQueryRow do not have classic getters and Jackson does not recognise methods alike value() by default. I propose to create Map<String, Object> and build required output and include needed properties manually:

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

and finally return:

return ResponseEntity.ok(n1QlResult);

Of course, when you have many methods like this you can write common layer which translates these kind of object to Map or write custom serialiser and configure ObjectMapper user by Spring container.

EDIT
In case you want to return only rows return:

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


来源:https://stackoverflow.com/questions/55179768/how-to-return-n1qlqueryresult-as-the-response-of-rest-api-for-couchbase-databse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!