2

ここが私の居場所です。JSON コンテンツを受け入れる MVC コントローラー メソッドがあります。JSON スキーマを使用して検証する必要があるため、コントローラーは要求本文を 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 のカスタム シリアライゼーションとデシリアライゼーションでオーバーライドできますが、探している「粗雑な」アプローチを超える可能性があります。

データ モデリングへのすべてのアプローチに適合する 1 つの靴が必要なようです。

マップを保存することをお勧めします

@Field
private Map<String, String> data;

このマップは非公開なので完璧です。

その後、2つの方法を持つことができます

1つのメソッドがそのようにマップに配置します

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 を処理しているのと同じ方法です。

これが理にかなっていることを願っています。

于 2014-07-21T06:02:43.780 に答える