2

这就是我所在的地方。我有一个接受 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 以我希望的方式运行?

4

1 回答 1

0

它不能那样工作,因为已经建立了序列化和反序列化约定。您可以使用 Jackson 中的自定义序列化和反序列化来覆盖这些约定——但这可能超出了您正在寻找的“粗略”方法。

我看到您想要一种适合所有数据建模的方法。

我可以推荐存储地图吗

@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 进行序列化/反序列化的内容。

我希望这是有道理的。

于 2014-07-21T06:02:43.780 回答