4

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;
        }
    }
}

2 Answers 2

6

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
2
  • Awesome, thank you I think this is a better approach
    – manza
    Commented Apr 20, 2016 at 2:30
  • It worked but how does an object value get tranformed into a List<Object> ? That looks like magic to me
    – MadMax
    Commented Nov 14, 2022 at 4:47
0

This solution will iterate through the JSON are serialize them into objects you defined as inner classes (Distribution, DistributionDetails) and add them to a list for you to use. Obviously you can manipulate the data differently if you desire but this should put you on the right path.

JSONParser parser = JSON.createParser(jsonStr);
ProcessorJSONController.Distribution[] distributions = new ProcessorJSONController.Distribution[]{};
ProcessorJSONController.DistributionDetails[] distributionDetails = new ProcessorJSONController.DistributionDetails[]{};
while (parser.nextToken() != null) {
    if(parser.getCurrentToken() == JSONToken.FIELD_NAME) {
        String currentPropertyName = parser.getText();
        if(currentPropertyName == 'VALUE1') {
            parser.nextToken();
            if(parser.getCurrentToken() == JSONTOken.START_ARRAY) {
                while(parser.nextToken() != null) {
                    if(parser.getCurrentToken() == JSONTOken.START_OBJECT) {
                        ProcessorJSONController.Distribution dist = (ProcessorJSONController.Distribution)parser.readValueAs(ProcessorJSONController.Distribution.class);
                        distributions.add(dist);
                    }
                }
            }
        } else if(currentPropertyName == 'VALUE3') {
            parser.nextToken();
            if(parser.getCurrentToken() == JSONTOken.START_ARRAY) {
                while(parser.nextToken() != null) {
                    if(parser.getCurrentToken() == JSONTOken.START_OBJECT) {
                        ProcessorJSONController.DistributionDetails details = (ProcessorJSONController.DistributionDetails)parser.readValueAs(ProcessorJSONController.Distribution.class);
                        distributionDetails.add(details);
                    }
                }
            }
        }
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .