这是我在的地方。我有一个接受JSON内容的MVC控制器方法。因为我需要使用JSON Schema验证它,我的控制器将请求体映射为Jackson JsonNode。
验证成功后,我需要将数据保存在Spring Couchbase存储库中。请考虑以下代码段:
public class Foo
{
@Id
private String _id;
@Version
private Long _rev;
@Field
private JsonNode nodeData;
// .. Other data and members.
}
//
// Repository
//
@Repository
public interface FooRepository extends CrudRepository<Foo, String> {
}
当我将这些元素存储到Couch存储库中时,我希望看到的是这样的:
{
"_class": "Foo",
"field1": "field 1 data",
"nodeData" : {
"Some" : "additional data",
"from" : "JsonNode"
}
}
相反,我在存储库中看到的是这样的:
{
"_class": "Foo",
"field1": "field 1 data",
"nodeData" : {
"_children": {
"Some": {
"_value": "additional data",
"_class": "com.fasterxml.jackson.databind.node.TextNode"
},
"From": {
"_value": "jsonNode",
"_class": "com.fasterxml.jackson.databind.node.TextNode"
},
"_nodeFactory": {
"_cfgBigDecimalExact": false
}
}
}
JsonNode的每个存储属性都使用类信息和其他元数据进行修饰,这是不可取的。
我的问题 - 是否有一种首选方式让CrudRepository以我希望的方式运行?
答案 0 :(得分:0)
它不起作用,因为已经建立了序列化和反序列化约定。您可以使用自定义序列化&amp ;;覆盖这些约定。杰克逊的反序列化 - 但这可能超出了你正在寻找的“原始”方法。
我看到你想要一种适合所有数据建模方法的鞋子。
我建议存储地图
@Field
private Map<String, String> data;
这张地图是私密的,所以它很完美。
然后你可以有两种方法
一种方法就像这样放入地图
ObjectMapper mapper = new ObjectMapper()
public void setFeild(String name, Object value) {
ObjectNode node new ObjectNode(JsonNodeFactory.instance);
node.put("clazz", value.getClass().getName());
if (value instance of String) {
node.put("value", value)
} else {
node.put("value", mapper.writeValueAsString(data));
}
data.put(name, node.toString());
}
另一个像地图一样从地图中获取
public Object getField(String name) {
if (data.contains(name)) {
JsonNode node = mapper.readValue(data.get(name), JsonNode.class);
Class clazz = Class.forName(node.get("class").textValue());
if (clazz.equals(String.class) {
return node.get("value").textValue();
} else {
return (Object) mapper.readValue(node.get("value"), clazz);
}
}
}
您应该更新此实现以处理Date,Integer,Boolean,Double ...等我处理String的方式相同 - POJO是您对json进行序列化/反序列化的内容。
我希望这是有道理的。