从 Json 数据中排除属性而不对其进行反序列化

Exclude properties from Json data without deserializing it

我有 Json 这样的数据:

{
"_id": "123",
"transaction": {
    "className": "ExpenseReport",
    "id": "789",
    "createdBy": {
        "firstName": "Donald",
        "lastName": "Morgan",
        "address": {
            "street1": "1362 Woodlawn Lane",
            "street2": "Suite #100805",
            "place": {
                "city": "Darien",
                "state": "CA",
                "country": "USA",
                "number": "OBJ-4823478",
                "createdBy": "Brett Wright"
            },
            "zip": 88884,
            "number": "OBJ-5740231",
            "createdBy": "Brett Wright"
        },
        "number": "OBJ-3561551",
        "createdBy": "Brett Wright"
    },
    "score": 12,
    "reasonCodes": [
        "these",
        "are",
        "strings"
    ]
}
}

在排除一些属性后我想要这个数据的一个子集,这样说:

{
"_id": "123",
"transactionType": "EXPENSE_REPORT",
"transaction": {
    "className": "ExpenseReport",
    "id": "789",
    "createdBy": {
        "firstName": "Donald",
        "lastName": "Morgan",
        "address": {
            "street1": "1362 Woodlawn Lane",
            "street2": "Suite #100805",
            "place": {
                "city": "Darien",
                "state": "CA",
                "country": "USA"
            },
            "createdBy": "Brett Wright"
        },
        "createdBy": "Brett Wright"
    },
    "score": 12
}
}

现在一种方法是反序列化原来的json数据成POJO,用Jackson Views注解需要的属性,然后序列化同样的 POJO 再次获取没有属性的 Json 数据。

但我想实现这样的结果 WITHOUT DESERIALIZING Json 数据,比如只解析 json 数据并删除键值如果在集合中找不到它们,则对。有人知道有这样做的图书馆吗?

Jackson 允许您使用 ObjectMapper.readTree()

仅执行解析步骤
JsonNode root = om.readTree(input);

生成的 JsonNodes 是可变的,所以像这样的东西可以完成工作:

ObjectNode place = (ObjectNode)(root.findPath("transaction")
    .findPath("createdBy")
    .findPath("address")
    .findPath("place")
);
place.remove("number");

这 -- 不幸的是 -- 不太好,但可以很容易地包装到采用 属性 路径的通用方法中:

void deleteProperty(JsonNode root, List<String> propPath)
{
   JsonNode node = root;

   for (String propName: propPath.subList(0, propPath.size() - 1)) {
       node = node.findPath(propName);
   }
   // completely ignore missing properties
   if ((! node.isMissingNode()) && (! node.isEmpty())) {
       if (node instanceof ObjectNode) {
           final ObjectNode parent = (ObjectNode)node;
           parent.remove(propPath.get(propPath.size() - 1));
       }
   }
}

然后可以使用writeTree()写出修改后的节点树。

属性 路径还有 property filter API. Unfortunately while it is easy to filter out individual properties with it, it is non-trivial to use it。例如,在您的情况下,普通过滤器只能过滤掉 all createdBy 属性。