Search code examples
javajsonscalajsonpath

jayway jsonpath throwing an error when reading a json path that does not exist despite being configured to


I have some json that is like this:

{
  "root": {
    "metadata": {
      "name": "Farmer John",
      "hasTractor": false
    },
    "plants": {
      "corn": 137.137,
      "soy": 0.45
    },
    "animals": {
      "cow": 4,
      "sheep": 12,
      "pig": 1
    },
    "family": {
      "isMarried": true
    }
  }
}  

That I am parsing like this using JsonPath:

val document = Configuration.defaultConfiguration()
        .addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL)
        .jsonProvider()
        .parse(jsonString): Object
val value = JsonPath.read(document, "$.root.family.hasChild"): Any  

But I am getting the error:

No results for path: $['root']['family']['hasChild']
com.jayway.jsonpath.PathNotFoundException: No results for path: $['root']['family']['hasChild']
    at com.jayway.jsonpath.internal.path.EvaluationContextImpl.getValue(EvaluationContextImpl.java:133)
    at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:102)  

I should be getting null because I have the config option Option.DEFAULT_PATH_LEAF_TO_NULL set in the document creation code right? But instead I am getting that error

Edit:
I was able to get it working by simply catching the error and returning null like this:

val value = try {
  JsonPath.read(document, "$.root.family.hasChild"): Any
} catch {
  case _: PathNotFoundException => null
}  

However, I am still looking for how to do it the "right" way


Solution

  • Try it like this using the JsonPath.parse() method:

    Configuration configuration = Configuration.builder().options(Option.DEFAULT_PATH_LEAF_TO_NULL).build();
    val value = JsonPath.parse(document, configuration).read("$.root.family.hasChild"));
    

    Whether this is more or less efficient than catching an exception might depend on the implementation. Looking at the Jayway code, if the option DEFAULT_PATH_LEAF_TO_NULL and a non-existing leaf is encountered then simply null is returned, otherwise, an exception is thrown. The difference is probably not noticeable when dealing with a low number of cases, but things could add up if this happens a lot.