有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在存储在Crudepository中的POJO中嵌入Jackson JsonNode

这就是我要说的。我有一个接受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> {
}

当我将这些元素存储到沙发存储库中时,我希望看到的是这样的东西:

{
  "_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的每个存储属性都用类信息和其他元数据修饰,这是不可取的

我的问题是——有没有更好的方法让积垢者按照我希望的方式行事


共 (1) 个答案

  1. # 1 楼答案

    它不能这样工作,因为序列化和反序列化约定已经建立。您可以通过自定义序列化覆盖这些约定&;在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);
             }
         }
    
    }
    

    您应该更新此实现以处理日期、整数、布尔值、双精度。。。我处理字符串POJO的方式与处理json的序列化/反序列化方式相同

    我希望这是有道理的