Vinod Jayachandran
Vinod Jayachandran

Reputation: 3898

how to Validate if JSON Path Exists in JSON

In a given json document, how to validate if a json path exists ?

I am using jayway-jsonpath and have the below code

JsonPath.read(jsonDocument, jsonPath)

The above code can potentially throw below exception

com.jayway.jsonpath.PathNotFoundException: No results for path: $['a.b.c']

In order to mitigate it, I intend to validate if the path exists before trying to read it with JsonPath.read

For reference I went through the following 2 documentations, but couldn't really get what I want.

  1. http://www.baeldung.com/guide-to-jayway-jsonpath
  2. https://github.com/json-path/JsonPath

Upvotes: 13

Views: 28961

Answers (2)

aberger
aberger

Reputation: 2397

You can also create a JsonPath object or ReadContext with a Configuration if you have a use case to check multiple paths.

    // Suppress errors thrown by JsonPath and instead return null if a path does not exist in a JSON blob.
    Configuration suppressExceptionConfiguration = Configuration
            .defaultConfiguration()
            .addOptions(Option.SUPPRESS_EXCEPTIONS);
    ReadContext jsonData = JsonPath.using(suppressExceptionConfiguration).parse(jsonString);

    for (int i = 0; i < listOfPaths.size(); i++) {
        String pathData = jsonData.read(listOfPaths.get(i));
        if (pathData != null) {
            // do something
        }

Upvotes: 3

gil.fernandes
gil.fernandes

Reputation: 14611

Whilst it is true that you can catch an exception, like it is mentioned in the comments there might be a more elegant way to check if a path exists without writing try catch blocks all over the code.

You can use the following configuration option with jayway-jsonpath:

com.jayway.jsonpath.Option.SUPPRESS_EXCEPTIONS

With this option active no exception is thrown. If you use the read method, it simply returns null whenever a path is not found.

Here is an example with JUnit 5 and AssertJ showing how you can use this configuration option, avoiding try / catch blocks just for checking if a json path exists:

@ParameterizedTest
@ArgumentsSource(CustomerProvider.class)
void replaceStructuredPhone(JsonPathReplacementArgument jsonPathReplacementArgument) {
    DocumentContext dc = jsonPathReplacementHelper.replaceStructuredPhone(
            JsonPath.parse(jsonPathReplacementArgument.getCustomerJson(),
                    Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS)),
            "$.cps[5].contactPhoneNumber", jsonPathReplacementArgument.getUnStructuredPhoneNumberType());
    UnStructuredPhoneNumberType unstructRes = dc.read("$.cps[5].contactPhoneNumber.unStructuredPhoneNumber");
    assertThat(unstructRes).isNotNull();
    // this path does not exist, since it should have been deleted.
    Object structRes = dc.read("$.cps[5].contactPhoneNumber.structuredPhoneNumber");
    assertThat(structRes).isNull();
}

Upvotes: 9

Related Questions