0

I'd like to be able to query a JSON object and modify it in a way that is structure-agnostic and doesn't involve marshalling to POJOs. Here's an example to illustrate.

{
  "user" : [ {
    "username" : "foo",
    "user-id" : "1234",
    "name" : {
      "first-name" : "John",
      "last-name" : "Smith"
    },
    "ssn": "123-45-6789"
  }, {
    "username" : "bar",
    "user-id" : "1235",
    "name" : {
      "first-name" : "Jane",
      "last-name" : "Doe"
    },
    "ssn": "098-76-5432"
  } ]
}

What I want to do is this:
Get the ssn nodes, retrieve their values, encrypt them, put the encrypted values back in the JSON, and return the whole thing. I've found two ways to do this so far:

  1. Marshalling to a User POJO
  2. Writing a method that iterates over the "user"s directly and modifies the ssn value.

The problem with either approach is that I have to generate "user" specific code. This is fine when I have only one data format, but I'm going to have dozens. I want to work more agnostically. Ideally I can do this with a line like this:

List<JsonNode> ssnNodes = jsonObj.match("$.user[*].ssn");

and then just iterate over the list -- just as I can with XML using XPath. This way I can maintain a list of json-paths to query with and that is as much as I need to know about the data.

Someone please tell me there is a way to do this in Java, but I haven't found a way so far. Thanks in advance!

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
Sabrina Star
  • 1
  • 1
  • 1
  • If your input is raw `JSON` payload you should use `JsonPath` to scan and change fields. If your input is a `Java` model you can write custom serialisers for specific fields. For example: [Jackson custom serialization and deserialization](https://stackoverflow.com/questions/55249054/jackson-custom-serialization-and-deserialization). – Michał Ziober Nov 12 '19 at 19:46
  • JsonPath is a great tool but unless I am missing something it seems I can't use it the way I am hoping to. Reading a JsonPath string with wildcards seems to return a list of values, not references to nodes in a document model, as I can do with javax.xml.xpath. So there's no way to iterate over a list of nodes, I have to iterate over a list of "users," which is the kind of code I'm trying to avoid. – Sabrina Star Nov 12 '19 at 20:43
  • I've also looked at Jackson's JsonPointer implementation, but it doesn't offer any sort of wildcard querying at all. – Sabrina Star Nov 12 '19 at 21:07
  • You can do that using `Option.AS_PATH_LIST` option. Take a look on this question and my answer: [How to get in Java all output paths of a JSONpath in order to replace existing values by a function of themseleves](https://stackoverflow.com/questions/55423089/how-to-get-in-java-all-output-paths-of-a-jsonpath-in-order-to-replace-existing-v). Also, you can play with online tool [jsonpath.herokuapp](http://jsonpath.herokuapp.com/) but select `Normalized path expressions` option instead of `Matching values`. – Michał Ziober Nov 13 '19 at 00:58
  • I will take a deeper look at that - thank you Michal! – Sabrina Star Nov 14 '19 at 13:50

0 Answers0