rrrocky
rrrocky

Reputation: 696

Exclude properties from Json data without deserializing it

I have Json data like this:

{
"_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"
    ]
}
}

I want a subset of this data after excluding some properties, say something like this:

{
"_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
}
}

Now one way would be to deserialize the original json data into a POJO, use Jackson Views to annotate the required properties, and then serialize the same POJO again to get the Json data without the properties.

But I want to achieve something like this WITHOUT DESERIALIZING the Json data, say by just parsing the json data and removing the key-value pairs if they are not found in a collection. Is anyone aware of any library that does that?

Upvotes: 2

Views: 1354

Answers (1)

dhke
dhke

Reputation: 15398

Jackson allows you to do only the parsing step using ObjectMapper.readTree()

JsonNode root = om.readTree(input);

The resulting JsonNodes are mutable, so something like this does the job:

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

This is --unfortunately-- not too nice, but can be easily wrapped into a generic method that takes a property path:

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));
       }
   }
}

It is then possible to write out the modified node tree using writeTree().

There is also the property filter API. Unfortunately while it is easy to filter out individual properties with it, it is non-trivial to use it for property paths. For example, in your case, the trivial filter can only filter out all createdBy properties.

Upvotes: 2

Related Questions