-1
{
    "icon": "service",
    "title": "A",
    "type": "service",
    "children": [
        {
            "icon": "sharedlibraries",
            "title": "sharedlibraries",
            "type": "sharedlibraries",
            "children": [
                {
                    "icon": "war",
                    "title": "abc.war ( ui-shared-lib )",
                    "path": "abc/common/Services/1.2.0/lib/comp.war",
                    "reference": >"abc/common/templates/applications/11.1.2.3.jar/config/config.xml",
                    "type": "sharedlibrary",
                    "version": "11.1.2.0@11.1.2.0",
                    "children": [
                        {
                            "icon": "jar",
                            "title": "comp1.jar",
                            "path": >"abc/common/SharedServices/1.2.0/lib/comp.war/WEB-INF/lib/comp.jar",
                            "reference": >"abc/common/Services/1.2.0/lib/comp.war/WEB-INF/lib",
                            "type": "jar",
                            "thirdpartyjar": "true"

                        }
                    ]
                },
:
:
:
}

I would need to retrieve, attribute "path", of all nodes with name "children", whose "thirdpartyjar" atribute= true. Is this possible using jackson?

Update: I tried following:

          public void parse(File file) throws JsonProcessingException, 
          IOException {
                   ObjectMapper objectMapper = new ObjectMapper();
                   //JsonNode rootNode = objectMapper.readTree(file);
                   Model model = objectMapper.readValue(file, Model.class);
                   listThirdPartyJars(model);
                   while (true) {
                   Model children = model.getChildren();
                   if (!(children == null)) {
                         listThirdPartyJars(children);
                         model = children;
                   } else {
                         break;
                   }
                 }
                 }

            public void listThirdPartyJars(Model model) {
            boolean thirdPartyJars = model.isThirdPartyJar();
            if (thirdPartyJars == true)
                System.out.println(model.getPath());
      }

But, came across following exception: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.manager.Model out of START_ARRAY token at [Source: D:\my_json.json; line: 4, column: 22] (through reference chain: com.manager.Model["children"])

Soumali Chatterjee
  • 309
  • 1
  • 4
  • 13

2 Answers2

1

Considering the JSON you posted in your question (with a few fixes to make it valid):

{
  "icon": "service",
  "title": "A",
  "type": "service",
  "children": [
    {
      "icon": "sharedlibraries",
      "title": "sharedlibraries",
      "type": "sharedlibraries",
      "children": [
        {
          "icon": "war",
          "title": "abc.war ( ui-shared-lib )",
          "path": "abc/common/Services/1.2.0/lib/comp.war",
          "reference": "abc/common/templates/applications/11.1.2.3.jar/config/config.xml",
          "type": "sharedlibrary",
          "version": "11.1.2.0@11.1.2.0",
          "children": [
            {
              "icon": "jar",
              "title": "comp1.jar",
              "path": "abc/common/SharedServices/1.2.0/lib/comp.war/WEB-INF/lib/comp.jar",
              "reference": "abc/common/Services/1.2.0/lib/comp.war/WEB-INF/lib",
              "type": "jar",
              "thirdpartyjar": "true"
            }
          ]
        }
      ]
    }
  ]
}

Using Jayway JsonPath and a query such as $..children[?(@.thirdpartyjar=='true')].path will do the trick and will give you the following result:

[
  "abc/common/SharedServices/1.2.0/lib/comp.war/WEB-INF/lib/comp.jar"
]

You can test it here.

Using Jayway JsonPath

To use Jayway JsonPath, add the following dependency to your project:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.3.0</version>
</dependency>

And then read the JSON document:

String json = "...";
List<String> paths = JsonPath.read(json, "$..children[?(@.thirdpartyjar=='true')].path");

Alternatively to Jayway JsonPath, you can map your JSON to Java classes (or simply use the Jackson Tree Model), parse the JSON using Jackson, iterate recursively over the tree and extract the data you need.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • Thanks . I am able to get correct output with jayway json filter expression "$..*.children[?(@.thirdpartyjar=='true')].path", in online jsonpath validator, but using java code, I am not getting any result. Any idea what may be wrong – Soumali Chatterjee Sep 13 '17 at 18:07
  • Thanks @Cássio Mazzochi Molin!. It worked. I was using older json-path jar , and reading the input json file, directly , without parsing. – Soumali Chatterjee Sep 14 '17 at 06:30
  • File jsonFile = new File("D://json//my_json.json"); List paths = JsonPath.parse(jsonFile).read( "$..*.children[?(@.thirdpartyjar=='true')].path"); – Soumali Chatterjee Sep 14 '17 at 06:32
  • is it possible, that we may get respective parent attributes along with children attributes? So the requirement is, getting 2 information: 1) Child jar relative path based on whether the same is a third party jar or not 2) Parent location hierarchy, till root . This information is there in the input json – Soumali Chatterjee Sep 15 '17 at 06:17
  • @SoumaliChatterjee Instead of using a query to select a single property (such as `path`), you can use a query such as `$..children[?(@.thirdpartyjar=='true')]` then map the result to a Java bean and get the desired values. Check the documentation for extra details. If you have other question, you may want to [ask a new question](https://stackoverflow.com/questions/ask). – cassiomolin Sep 15 '17 at 09:37
0

Yes, it's possible. You would need to have a model which references itself as an attribute, somewhat like :

public class Model {
    String icon;
    String title;
    String path;
    String reference;
    String type;          
    String version;
    boolean thirdPartyJar;
    Model children;
    ...getters, setters and overriden methods
}

And you can map your Json string to this object using ObjectMapper to further access the children with attribute thirdPartyJar as true.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • public void parse(File file) { Model model = objectMapper.readValue(file, Model.class); listThirdPartyJars(model); while (true) { Model children = model.getChildren(); if (!(children == null)) { listThirdPartyJars(children); model = children; } else { break; } } – Soumali Chatterjee Sep 13 '17 at 18:00
  • @SoumaliChatterjee Please don't post code in comments. Either update your question or ask a new one. – Naman Sep 13 '17 at 18:01