JSON Deserialization in Salesforce


I have been several posts recently on the Developer Boards around JSON deserialization and some weird and convoluted ways to convert it into something that is useful for Salesforce.  Let’s talk about what I have found is the cleanest way to handle JSON deserialization.

JSON Payload

Let’s take a look at our JSON payload.  I am taking the payload from the docsample Heroku app since it’s an easy way to get consistent data from a webservice.

  "invoiceList": [
      "totalPrice": 5.5,
      "statementDate": "2011-10-04T16:58:54.858Z",
      "lineItems": [
          "UnitPrice": 1,
          "Quantity": 5,
          "ProductName": "Pencil"
          "UnitPrice": 0.5,
          "Quantity": 1,
          "ProductName": "Eraser"
      "invoiceNumber": 1
      "totalPrice": 11.5,
      "statementDate": "2011-10-04T16:58:54.858Z",
      "lineItems": [
          "UnitPrice": 6,
          "Quantity": 1,
          "ProductName": "Notebook"
          "UnitPrice": 2.5,
          "Quantity": 1,
          "ProductName": "Ruler"
          "UnitPrice": 1.5,
          "Quantity": 2,
          "ProductName": "Pen"
      "invoiceNumber": 2

So we can see here that the data provided is an invoice list and each invoice contains data and line items for that invoice.

JSON Deserialization

Data Structure

Now we need to create a data structure to hold our the JSON we deserialize

public class InvoiceWrapper {
    public class LineItem {
        public Double unitPrice {get; set;}
        public Double quantity {get; set;}
        public String productName {get; set;}

        public Double getLineItemTotal() {
            return this.unitPrice * this.quantity;

    public class Invoice {
        public Double totalPrice {get; set;}
        public DateTime statementDate {get; set;}
        public String contactnumber {get; set;}
        public List<LineItem> lineItems {get; set;}
        public Integer invoiceNumber {get; set;}

    public List<Invoice> invoiceList {get; set;}

This wrapper class now contains our two sub-classes (LineItem and Invoice) as well as our variable for our invoice list.  The nice thing about doing it as a class is we can add helper methods to also manipulate data.  There is a getLineItemTotal method that we can use in our display.

Data Parsing

Now we need to pull the data from the endpoint and using JSON deserialization push it into our data structure.

public class JSONDeserialize {
    public InvoiceWrapper wrapper {

    public void deserialize() {
        Http h = new Http();
        HttpRequest request = new HttpRequest();
        request.setHeader('Content-type', 'application/json');

        HttpResponse response = h.send(request);

        wrapper = (InvoiceWrapper) JSON.deserializeStrict(response.getBody(), InvoiceWrapper.class);

If your JSON data is going to change (or could change) you can use deserialize instead of deserializeStrict to make it not explode when the JSON deserialization happens.

Data Display

Now that we have a way to get the data in a meaningful structure, let’s display it on a Visualforce page

<apex:page controller="JSONDeserialize">
    <apex:form >
        <apex:pageBlock title="JSON Deserialize Response">
            <apex:pageBlockButtons >
                <apex:commandButton value="submit" action="{!deserialize}" reRender="invoiceBlock"/>
            <apex:pageBlockSection id="invoiceBlock" columns="1">
                <apex:repeat value="{!wrapper.invoiceList}" var="invoice">
                    <apex:pageBlockSection columns="2">
                        <apex:facet name="header">Invoice {!invoice.invoiceNumber}</apex:facet>
                        <apex:pageBlockSectionItem >
                            <apex:outputLabel value="Total Price" for="totalPrice" />
                            <apex:outputText value="{!invoice.totalPrice}" id="totalPrice" />
                        <apex:pageBlockSectionItem >
                            <apex:outputLabel value="Statement Date" for="statementDate" />
                            <apex:outputText value="{!invoice.statementDate}" id="statementDate" />
                    <apex:pageBlockSection columns="1">
                        <apex:facet name="header">Invoice {!invoice.invoiceNumber} Items</apex:facet>
                        <apex:pageBlockTable value="{!invoice.lineItems}" var="item" id="lineItems">
                            <apex:column value="{!item.productName}" headerValue="Product Name" />
                            <apex:column value="{!item.quantity}" headerValue="Quantity" />
                            <apex:column value="{!item.unitPrice}" headerValue="Unit Price" />
                            <apex:column value="{!item.lineItemTotal}" headerValue="Total" />

Now when we click the submit button we can see the data coming in and when it’s pressed we deserialize the data and reRender the section

JSON Deserialization in action

This entry was posted in Development, Salesforce and tagged , , . Bookmark the permalink.
  • JimBTek

    This article makes it really straightforward to see how to do this step by step. Would be interesting to have a second piece that includes storing the data in a Salesforce custom object, and perhaps even different ways of getting this data to sync 1-way or 2-ways. Thanks for the great article!

  • You mean extending this so that the data in InvoiceWrapper is stored into an Invoice__c object? Can you expand upon what you mean by “1-way or 2-ways” sync?

  • JimBTek

    Yeah storing the data in a custom object.

    1-way: Sync data from JSON to Salesforce ongoing (think syncing in invoices for read only purpose in Salesforce

    2-way: User edits the Invoice record in Salesforce and it pushes back through JSON to Heroku, etc.

    Currently on a project that does 2-way syncing of invoices between Salesforce and Quickbooks Online, but we use a 3rd party syncing tool that uses XML to map across the two. It would be interesting to see more of how to roll your own connection.

  • Jerry Clifft

    I would really like to see this write the data to a custom object/fields instead of displaying to visualforce.

  • I’ll try to write something up for you, but there are two ways to do this. You can do the object way above and add a method that converts the data to an sObject or if the incoming JSON is in the same format as your sObject you can just deserialize it directly using sObject.class

  • Hi, I just tried to use your method in my org but struggling to get the results.


  • I’ve replied back to your post

  • Hara Prasad Sahoo

    Just a small correction, I had to change the datatype of Quantity field to Double.
    public class lineitem{
    public Double unitprice{get;set;}
    public Double quantity{get;set;}
    public String productname{get;set;}

    rest all is good, works like a charm

  • It was already set as a double in the on the post. Did I miss a place?

  • Hara Prasad Sahoo

    my bad, i might have missed it:)

  • Hara Prasad Sahoo

    I was working on a similar task.
    I have tried to use a wrapper class to deserialise the json and put it into a wrapper class, which I have declared earlier.
    I am getting an error at this point below:
    jsonOutput results = (jsonOutput) JSON.deserialize(response.getBody(), jsonOutput.class);

    Error is :19:26:06:943 FATAL_ERROR System.JSONException: Malformed JSON: Expected ‘{‘ at the beginning of object

    please advise if I am missing anything here.

    public with sharing class WarehouseCalloutService {

    private static final String WAREHOUSE_URL = ‘https://th-superbadge-apex.herokuapp.com/equipment’;

    // wrapper class
    public class Jsonwrapper{
    public String x_id;
    public Boolean replacement;
    public Integer quantity;
    public String name;
    public Integer maintenanceperiod;
    public Integer lifespan;
    public Integer cost;
    public String sku;

    public class JsonOutput{
    public Jsonwrapper wrapper;
    public static void runWarehouseEquipmentSync(){
    Http h = new Http();
    HttpRequest request = new HttpRequest();
    request.setHeader(‘Content-type’, ‘application/json’);

    HttpResponse response = h.send(request);

    if (response.getStatusCode() == 200) {

    jsonOutput results = (jsonOutput) JSON.deserialize(response.getBody(), jsonOutput.class);
    system.debug(‘##’ + results);



  • The problem you are having is because you’re not parsing the JSON in the way that it is formatted. You need to parse a list of “Jsonwrapper” instead. Below I’ve renamed your “Jsonwrapper” class to be Equipment (to better line up with what it is)

    public class Equipment {
    /* Elements go here */

    /* Rest of http stuff goes here */

    List = (List) JSON.deserialize(response.getBody(), List.class);

  • Sagar Panwar

    Hey! Patrick Connelly, Thank you my friend. The example is great. It worked for me. I am new to salesforce and I have a question.
    Can we use the same process to fetch data from woo commerce to our salesforce. I don’t want to use external plugins.

  • Yes, you should be able to do this with any REST endpoint. I recommend going over the Apex Integration Services (specifically the Apex REST Callouts module) [1]. Be warned that depending on the number of licenses you have, you want to monitor your API limits. You may also want to look at implementing platform cache [2] to reduce the number of API calls you make, if your data doesn’t change super frequently.

    [1] https://trailhead.salesforce.com/modules/apex_integration_services
    [2] https://trailhead.salesforce.com/modules/platform_cache