[SalesForce] Processing a json api response using JSONParser class

I am new in using JSONParser class, I am struggling a bit to understand how to use it.

The string that I want to use this, is a reponse from an API call, it is a really long string (about 5.4 million characters), so i guess this is the best way to process this response.

The response looks like the json below, where I am not interested in VALUE2 and VALUE4. I would like to process VALUE1 and VALUE3. I have created an object called Distribution__c, with the fields:
PKT, CODE, COLOR, STATUS, WEIGHT, YEARS, LOC and SHOP, FABRIC, CITY, PLOT

and the purpose is to each time the api is call it inserts this values into distribution.

In the below example VALUE1, has 2 arrays in it, but this value always changes

  {
    "VALUE1": [
      {
        "PKT": "0.00",
        "CODE": "1299600",
        "COLOR": "GREEN",
        "STATUS": "GOOD",
        "WEIGHT": "6211",
        "YEARS": "5",
        "LOC": "SYD"
      }
      {
        "PKT": "0.01",
        "CODE": "129400",
        "COLOR": "RED",
        "STATUS": "POOR",
        "WEIGHT": "621",
        "YEARS": "1",
        "LOC": "SYD"
      }
    ],
    "VALUE2": [
      "PKT",
      "CODE",
      "COLOR",
      "STATUS",
      "WEIGHT",
      "YEARS",
      "LOC"
    ],
    "VALUE3": {
      "SHOP": "https://s3.amazonaws.com/SHOP/",
      "FABRIC": "https://s3.amazonaws.com/FABRIC/",
      "CITY": "http://s3.amazonaws.com/CITY/",
      "PLOT": "http://s3.amazonaws.com/PLOT/"
    },
    "VALUE4": [
      "SHOP",
      "FABRIC",
      "CITY",
      "PLOT"
    ]
  }

My code looks something like this: I honestly cant see how to manipulate the while to create the list for VALUES1 AND also how to differentiate when the loop reaches VALUE3, as this values have to be added into the distributions

public with sharing class ProcessorJSONController {
    public String jsonStr { get; set; }
    public List<Distribution> dist { get; set; }   
    public List<DistributionDetails> distDetails { get; set; }   

    public ProcessorJSONController() {
        dist = new List<Distribution>();
        distDetails = new List<DistributionDetails>();
        //I HAVE MANUALLY MODIFY THIS VALUE BUT HERE WILL BE THE RESPONSE
        jsonStr = '{"VALUE1":[{"PKT":"0.00","CODE":"1299600","COLOR":"GREEN","STATUS":"GOOD","WEIGHT":"6211","YEARS":"5","LOC":"SYD"},{"PKT":"0.01","CODE":"129400","COLOR":"RED","STATUS":"POOR","WEIGHT":"621","YEARS":"1","LOC":"SYD"}],"VALUE2":["PKT","CODE","COLOR","STATUS","WEIGHT","YEARS","LOC"],"VALUE3":{"SHOP":"https://s3.amazonaws.com/SHOP/","FABRIC":"https://s3.amazonaws.com/FABRIC/","CITY":"http://s3.amazonaws.com/CITY/","PLOT":"http://s3.amazonaws.com/PLOT/"},"VALUE4":["SHOP","FABRIC","CITY","PLOT"]}';
        JSONParser parser = JSON.createParser(jsonStr);
        String text = '';
        while (parser.nextToken() != null) {
            if(parser.getCurrentToken() == JSONToken.START_OBJECT){
                parser.nextToken();
                text = parser.getText() + ', ' + text;
            }
            //System.debug(parser.getText() + parser.nextToken() + ' - ' + parser.getText());
            if (parser.getCurrentToken() == JSONToken.START_ARRAY) {
                //parser.nextToken();
                text = parser.getText() + ', ' + text;
            }
        }
    }

    public class Distribution {
        public Double PKT { get; set; }
        public String CODE { get; set; }
        public String COLOR { get; set; }
        public String STATUS { get; set; }
        public String WEIGHT { get; set; }
        public Integer YEARS { get; set; }
        public String LOC { get; set; }
        public String SHOP { get; set; }
        public String FABRIC { get; set; }
        public String CITY { get; set; }
        public String PLOT { get; set; }        
        public Distribution (Double PKT, String CODE, String COLOR, String STATUS, String WEIGHT, Integer YEARS, String LOC, String SHOP, String FABRIC, String CITY, String PLOT){
            this.PKT    = PKT;
            this.CODE   = CODE;
            this.COLOR  = COLOR;
            this.STATUS = STATUS;
            this.WEIGHT = WEIGHT;
            this.YEARS  = YEARS;
            this.LOC    = LOC;
            this.SHOP   = SHOP;
            this.FABRIC = FABRIC;
            this.CITY   = CITY;
            this.PLOT   = PLOT;         
        }
    }

    public class DistributionDetails{
        public String SHOP { get; set; }
        public String FABRIC { get; set; }
        public String CITY { get; set; }
        public String PLOT { get; set; }

        public DistributionDetails (String SHOP, String FABRIC, String CITY, String PLOT){
            this.SHOP   = SHOP;
            this.FABRIC = FABRIC;
            this.CITY   = CITY;
            this.PLOT   = PLOT;
        }
    }
}

Best Answer

There is the DeserializeUntyped method that comes to the rescue in these more complex cases. Below is an example of one possible way how to tackle this. Based on the example for VALUE1 you should be able to work out the rest:

List <sObject> distributions = new List <sObject> ();

// Deserialize the JSON to a map of key => value
Map <String, Object> root = (Map <String, Object>) JSON.deserializeUntyped(jsonStr);

// Get the List of objects from VALUE1
List <Object> value1 = (List<Object>) root.get('VALUE1');

// Go through each of the objects
for (Object obj : value1)
{
    // Cast the object to a map of key => value
    Map <String, Object> objectMap = (Map <String, Object>) obj;

    // Create a Distribution__c sObject
    sObject distribution = new Distribution__c();

    // For each of the keys in the VALUE1 objects
    for (String key : objectMap.keySet())
    {
        // Assuming all the keys from the JSON match the API field names by appending __c
        // Copy the values from the JSON object into the sObject
        // Missing fields will be set to NULL
        distribution.put(key + '__c', objectMap.get(key));

        // add the sObject to the list
        distributions.add(distribution);
    }
}

// do something with the list of distributions
Related Topic