1

Getting Malformed JSON: Expected '[' at the beginning of List/Set while displaying External Data in Salesforce.

My Apex class - Calloutcontroller1.apxc

public class Calloutcontroller1 {
public List<consolewrap1> ConsoleWrapperList{get;set;}    
public List<consolewrap1> getperformcallout(){        
ConsoleWrapperList = new List<consolewrap1>();         
HttpRequest req = new HttpRequest();        
HttpResponse res = new HttpResponse();        
Http http = new Http();        
    req.setEndpoint('http://************************/sap/opu/odata/SAP/ZORDERS_INFO_SRV/ZORDERN_ETSet');        
    req.setMethod('GET'); 

    String username = '******';
    String password = '*********';

    Blob headerValue = Blob.valueOf(username + ':' + password);
    String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
    req.setHeader('Authorization', authorizationHeader);
    req.setHeader('x-csrf-token', 'Fetch');
    req.setHeader('Accept', 'application/json');

    res = http.send(req);

    if(res.getstatusCode() == 200 && res.getbody() != null){ 
        ConsoleWrapperList=(List<consolewrap1>)json.deserialize(res.getbody(),List<consolewrap1>.class);            
    }        
    return consolewrapperlist;        
}    

My VisualForce Page

<apex:page controller="Calloutcontroller1" title="JSON table" >    
<apex:form >        
    <apex:pageBlock >            
      <apex:pageBlockTable value="{!performcallout}" var="wrap" width="100%">                
            <apex:column headerValue="Order" value="{!wrap.Orderid}"/>                
            <apex:column headerValue="Customer" value="{!wrap.Customerid}"/> 

            <apex:column headerValue="Ship via" value="{!wrap.Shipvia}"/>                
            <apex:column headerValue="Ship Name" value="{!wrap.Shipname}"/>                
            <apex:column headerValue="Ship Address" value="{!wrap.Shipaddress}"/>
            <apex:column headerValue="Ship City" value="{!wrap.Shipcity}"/>
            <apex:column headerValue="Ship Region" value="{!wrap.Shipregion}"/>

            <apex:column headerValue="Returnprd Code" value="{!wrap.Returnprdcode}"/>                
            <apex:column headerValue="Returnprd Qty" value="{!wrap.Returnprdqty}"/>                
            <apex:column headerValue="Replaceprd Code" value="{!wrap.Replaceprdcode}"/>
            <apex:column headerValue="Replaceprd Qty" value="{!wrap.Replaceprdqty}"/>              
        </apex:pageBlockTable>    
    </apex:pageBlock>        
</apex:form>    

Consolewrap1.apxc

public class Consolewrap1 {  
public String Orderid{get;set;}
public String Customerid{get;set;} 

public String Shipvia{get;set;}    
public String Shipname{get;set;}    
public String Shipaddress{get;set;}
public String Shipcity{get;set;}    
public String Shipregion{get;set;} 

public String Returnprdcode{get;set;}
public String Returnprdqty{get;set;}    
public String Replaceprdcode{get;set;}    
public String Replaceprdqty{get;set;}}

JSON Data

 {
   "d":{
      "results":[
         {
            "__metadata":{
               "id":"http://************************/sap/opu/odata/SAP/ZORDERS_INFO_SRV/ZORDERN_ETSet('*******')",
               "uri":"http://************************/sap/opu/odata/SAP/ZORDERS_INFO_SRV/ZORDERN_ETSet('*******')",
               "type":"ZORDERS_INFO_SRV.ZORDERN_ET"
            },
            "Orderid":"456827",
            "Customerid":"9632587410",
            "Shipvia":"UPS",
            "Shipname":"KATHRYN KOLDER",
            "Shipaddress":"C/ARAQUIL, 671",
            "Shipcity":"CALIFORNIA",
            "Shipregion":"US",
            "Returnprdcode":"AKG N20",
            "Returnprdqty":"1",
            "Replaceprdcode":"AKG N20",
            "Replaceprdqty":"1"
         },  
      ]
   }
}

Please Help.

2 Answers 2

3

Your class structure does not reflect your payload structure, but rather one nested attribute. You could change your class structure or use untyped Map<String, Object> to traverse to the part of the payload you actually care about.

Strongly Typed:

public class FullPayload
{
    Intermediary d;
    class Intermediary
    {
        List<ConsoleWrap1> results;
    }
}

FullPayload data = (FullPayload)JSON.deserialize(myPayload, FullPayload.class);
List<ConsoleWrap1> wrappers = data.d.results;

Untyped:

Map<String, Object> data = (Map<String, Object>)JSON.deserializeUntyped(myPayload);
Map<String, Object> d = data.get('d');
List<ConsoleWrap1> wrappers = (List<ConsoleWrap1>)d.get('results');
2

Your Consolewrap1 class doesn't match the JSON. You have an Object with a value of "d", and within that a List of Consolewrap1 items. So you need another layer to your code:

public class Wrapper1 {
  public Wrapper2 d;
}
public class Wrapper2 {
  public Consolewrap1[] results;
}

And you need to start from there:

ConsoleWrapperList =((Wrapper1)json.deserialize(res.getbody(),Wrapper1.class)).d.results;

You must log in to answer this question.

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