Woods
Woods

Reputation: 81

Iterate over JSON and add the list array into the object/array

I have these two JSON arrays:

{ 
  "Person": {
    "Info": [
      "name": "Becky",
      "age": 14
    ]
   },
  "Fruits": [
    {
      "name": "avocado",
      "organic": true
    },
    {
      "name": "mango",
      "organic": true
    }
  ],
  "Vegetables": [
    {
      "name": "brocoli",
      "organic": true
    },
    {
      "name": "lettuce",
      "organic": true
    }
  ]
}

What I am trying to do is to use Jackson and Gson libraries to make everything look pretty.

Something like this. This works fine with Gson. So the output I want is:

{ 
  "Person": {
    "Info": [
      "name":"Becky",
      "age": 14
    ]
  },
  "FruitsList": {
    "Fruits": [
      {
        "name": "avocado",
        "organic": true
      },
      {
        "name": "mango",
        "organic": true
      }
    ]
  },
  "VegetablesList": {
    "Vegetables": [
      {
        "name": "brocoli",
        "organic": true
      },
      {
        "name": "lettuce",
        "organic": true
      }
    ]
  }
}

I have set my classes as:

class Person{
   private List<Info> InfoList;
   //Set and get were set
}

class Info{
   private String name;
   private int age;
   //Set and get were set
}

class Fruits{
   private String name;
   private boolean organic;
   //Set and get were set
   public String toString(){
            return "Fruits:{" +
            "name:'" + name+ '\'' +
            ", organic:" + organic+'\''+
            '}';
   }
 }

 class Vegetables{
   private String name;
   private boolean;
   //Set and get were set
   public String toString(){
            return "Fruits:[" +
            "name:'" + name+ '\'' +
            ", organic:" + organic+'\''+
            ']';
   }
 }

class rootFinal{
    private List<Fruits> fruitList;
    private List<Vegetables> vegetablesList;
    private List<Person> personList;
    //Set and get were set
}

class mainJson{
   final InputStream fileData = ..("testPVF.json");

   ObjectMapper map = new Ob..();
   rootFinal root = map.readValue(fileData,rootFinal.class);
   // I can access each class with 
   System.out.printl(root.getHeaderList.get(0));
}

This outputs...

[Fruit{name:'avocado', organic:true}, Fruit{name:'mango', organic:true}]

But this is not what I want.

I am trying to do an iteration over the JSON file or somehow if there is a better way to check an array exists. Add additional object/array to it.

If I find Veg or Fruit I want to somehow add VegList and FruitList as shown. It should ignore the "Person": {} since it's in a {} symbol.

Is there a way to do this with Gson?

Upvotes: 2

Views: 4943

Answers (2)

Michał Ziober
Michał Ziober

Reputation: 38690

If I understand you correctly, you want to wrap every JSON Array node using JSON Object node. To do this, you do not need to use POJO model, you can read JSON payload as ObjectNode and use it's API to update it.

Jackson

Simple example with Jackson library:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.File;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

public class JsonObjectApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        ObjectNode root = (ObjectNode) mapper.readTree(jsonFile);

        Map<String, JsonNode> valuesToAdd = new LinkedHashMap<>();

        // create fields iterator
        Iterator<Map.Entry<String, JsonNode>> fieldsIterator = root.fields();
        while (fieldsIterator.hasNext()) {
            Map.Entry<String, JsonNode> entry = fieldsIterator.next();

            // if entry represents array
            if (entry.getValue().isArray()) {
                // create wrapper object
                ObjectNode arrayWrapper = mapper.getNodeFactory().objectNode();
                arrayWrapper.set(entry.getKey(), root.get(entry.getKey()));

                valuesToAdd.put(entry.getKey(), arrayWrapper);

                // remove it from object.
                fieldsIterator.remove();
            }
        }

        valuesToAdd.forEach((k, v) -> root.set(k + "List", v));

        System.out.println(mapper.writeValueAsString(root));
    }
}

Above code prints for your JSON:

{
  "Person" : {
    "Info" : [ {
      "name" : "Becky",
      "age" : 14
    } ]
  },
  "FruitsList" : {
    "Fruits" : [ {
      "name" : "avocado",
      "organic" : true
    }, {
      "name" : "mango",
      "organic" : true
    } ]
  },
  "VegetablesList" : {
    "Vegetables" : [ {
      "name" : "brocoli",
      "organic" : true
    }, {
      "name" : "lettuce",
      "organic" : true
    } ]
  }
}

Gson

Very similar solution we could implement with Gson library:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import java.io.File;
import java.io.FileReader;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

public class GsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .create();

        try (FileReader reader = new FileReader(jsonFile)) {
            JsonObject root = gson.fromJson(reader, JsonObject.class);

            Map<String, JsonElement> valuesToAdd = new LinkedHashMap<>();

            // create fields iterator
            Iterator<Map.Entry<String, JsonElement>> fieldsIterator = root.entrySet().iterator();
            while (fieldsIterator.hasNext()) {
                Map.Entry<String, JsonElement> entry = fieldsIterator.next();
                // if entry represents array
                if (entry.getValue().isJsonArray()) {
                    // create wrapper object
                    JsonObject arrayWrapper = new JsonObject();
                    arrayWrapper.add(entry.getKey(), root.get(entry.getKey()));

                    valuesToAdd.put(entry.getKey(), arrayWrapper);

                    // remove it from object.
                    fieldsIterator.remove();
                }
            }

            valuesToAdd.forEach((k, v) -> root.add(k + "List", v));

            System.out.println(gson.toJson(root));
        }
    }
}

Output is the same.

Upvotes: 3

Nagendra
Nagendra

Reputation: 51

Check Get Pretty Printer

Also check specific APIs for Pretty Printing

Sample Code:

//This example is using Input as JSONNode
//One can serialize POJOs to JSONNode using ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(
					inputNode)

Upvotes: 0

Related Questions