[SalesForce] what is difference between JSON generator and JSON parser

I am in learning phase and strucked that what to choose JSON generator or JSON parser when response is coming from 3rd party and type REST webservice.

In Apex guide it showing

Using the JSONGenerator class methods, you can generate standard JSON-encoded content.
Use the JSONParser class methods to parse JSON-encoded content.

Can anyone please guide me with example.

Best Answer

The two are opposite features. The JSONGenerator takes data input and outputs JSON strings. The JSONParser takes JSON string input and outputs objects.

If you're sending data to an outside source, either for a client calling your code, or sending data to a server, use the generator. If you're receiving data from an outside source, either from a client or from a server response, use the parser.

/*************************************************************************\
|  /--------\  Call to SFDC    /-----------\   Http Callout   /--------\  |
|  |        | ---- Parser ---> |           | -- Generator --> |        |  |
|  | Client |                  | Apex Code |                  | Server |  |
|  |        | <-- Generator -- |           | <--- Parser ---- |        |  |
|  \--------/   Return Data    \-----------/   Http Response  \--------/  |
\*************************************************************************/

However, if you want efficient code, you should use neither, and stick with JSON.serialize, JSON.deserialize, or JSON.deserializeUntyped. JSON.serialize is a quicker version of the JSONParser, and the deserialize methods are a quicker version of the JSONGenerator.

The JSONGenerator has an example, which I'll copy-paste for you here:

public class JSONGeneratorSample{

    public class A { 
        String str;

        public A(String s) { str = s; }
    }

    static void generateJSONContent() {
        // Create a JSONGenerator object.
        // Pass true to the constructor for pretty print formatting.
        JSONGenerator gen = JSON.createGenerator(true);

        // Create a list of integers to write to the JSON string.
        List<integer> intlist = new List<integer>();
        intlist.add(1);
        intlist.add(2);
        intlist.add(3);

        // Create an object to write to the JSON string.
        A x = new A('X');

        // Write data to the JSON string.
        gen.writeStartObject();
        gen.writeNumberField('abc', 1.21);
        gen.writeStringField('def', 'xyz');
        gen.writeFieldName('ghi');
        gen.writeStartObject();

        gen.writeObjectField('aaa', intlist);

        gen.writeEndObject();

        gen.writeFieldName('Object A');

        gen.writeObject(x);

        gen.writeEndObject();

        // Get the JSON string.
        String pretty = gen.getAsString();

        System.assertEquals('{\n' +
        '  "abc" : 1.21,\n' +
        '  "def" : "xyz",\n' +
        '  "ghi" : {\n' +
        '    "aaa" : [ 1, 2, 3 ]\n' +
        '  },\n' +
        '  "Object A" : {\n' +
        '    "str" : "X"\n' +
        '  }\n' +
        '}', pretty);
    }
}

The JSONParser also has an example, which I've also included here.

public static void parseJSONString() {
    String jsonStr = 
        '{"invoiceList":[' +
        '{"totalPrice":5.5,"statementDate":"2011-10-04T16:58:54.858Z","lineItems":[' +
            '{"UnitPrice":1.0,"Quantity":5.0,"ProductName":"Pencil"},' +
            '{"UnitPrice":0.5,"Quantity":1.0,"ProductName":"Eraser"}],' +
                '"invoiceNumber":1},' +
        '{"totalPrice":11.5,"statementDate":"2011-10-04T16:58:54.858Z","lineItems":[' +
            '{"UnitPrice":6.0,"Quantity":1.0,"ProductName":"Notebook"},' +
            '{"UnitPrice":2.5,"Quantity":1.0,"ProductName":"Ruler"},' +
            '{"UnitPrice":1.5,"Quantity":2.0,"ProductName":"Pen"}],"invoiceNumber":2}' +
        ']}';

    // Parse entire JSON response.
    JSONParser parser = JSON.createParser(jsonStr);
    while (parser.nextToken() != null) {
        // Start at the array of invoices.
        if (parser.getCurrentToken() == JSONToken.START_ARRAY) {
            while (parser.nextToken() != null) {
                // Advance to the start object marker to
                //  find next invoice statement object.
                if (parser.getCurrentToken() == JSONToken.START_OBJECT) {
                    // Read entire invoice object, including its array of line items.
                    Invoice inv = (Invoice)parser.readValueAs(Invoice.class);
                    system.debug('Invoice number: ' + inv.invoiceNumber);
                    system.debug('Size of list items: ' + inv.lineItems.size());
                    // For debugging purposes, serialize again to verify what was parsed.
                    String s = JSON.serialize(inv);
                    system.debug('Serialized invoice: ' + s);

                    // Skip the child start array and start object markers.
                    parser.skipChildren();
                }
            }
        }
    }
} 

// Inner classes used for serialization by readValuesAs(). 

public class Invoice {
    public Double totalPrice;
    public DateTime statementDate;
    public Long invoiceNumber;
    List<LineItem> lineItems;

    public Invoice(Double price, DateTime dt, Long invNumber, List<LineItem> liList) {
        totalPrice = price;
        statementDate = dt;
        invoiceNumber = invNumber;
        lineItems = liList.clone();
    }
}  

public class LineItem {
    public Double unitPrice;
    public Double quantity;
    public String productName;
}

As you can see, reading and writing are both very tedious to do, and you should consider using these classes only as a last resort.

Related Topic