[SalesForce] System.JSONException: Unexpected character (‘<' (code 60)): expected a valid value

Code is as below
VF

<apex:page controller="Calloutcontroller" title="JSON Tutors table" >

<apex:form >

<apex:pageBlock >

<apex:pageBlockTable value="{!performcallout}" var="wrap">

<apex:column headerValue="class id" value="{!wrap.class_id}"/>

<apex:column headerValue="class time" value="{!wrap.class_time}"/>

<apex:column headerValue="tutor id" value="{!wrap.tutor_id}"/>

<apex:column headerValue="tutor name" value="{!wrap.tutor_name}"/>

<apex:column headerValue="tutor email" value="{!wrap.tutor_email}"/>

<apex:column headerValue="tutor phone" value="{!wrap.tutor_phone}"/>

</apex:pageBlockTable>

</apex:pageBlock>

</apex:form>

</apex:page>

Controller

public class Calloutcontroller {

public List<consolewrap> ConsoleWrapperList{get;set;}

public List<consolewrap> getperformcallout(){

ConsoleWrapperList = new List<consolewrap>();

HttpRequest req = new HttpRequest();

HttpResponse res = new HttpResponse();

Http http = new Http();

req.setEndpoint('http://www.itutorindia.com/angularjs/api/smallWidget/tutorHourSalesForce');

req.setMethod('GET');
req.setHeader('Content-Type', 'application/json');

res = http.send(req);

//if(res.getstatusCode() == 200 && res.getbody() != null){
//system.debug('Response is getting: ' + res.getBody());
if(res.getstatusCode() == 200 && res.getbody() != null){
system.debug('Response body result is: ' + res.getBody());
ConsoleWrapperList=(List<consolewrap>)json.deserialize(res.getbody(),List<consolewrap>.class);

//ConsoleWrapperList=(List<consolewrap>)json.deserialize(res.getbody(),List<consolewrap>.class);
}
return ConsoleWrapperList;
}
}

public class consolewrap {
@AuraEnabled
public String class_id{get;set;}@AuraEnabled
public String class_time{get;set;}@AuraEnabled
public String tutor_id{get;set;}@AuraEnabled
public String tutor_name{get;set;}@AuraEnabled
public String tutor_email{get;set;} @AuraEnabled
public String tutor_phone{get;set;}
}

Best Answer

The call you are making is returning a Table and HTML because the Accept header is not explicitly set.

Add the header:

req.setHeader('Accept','application/json'); and it will work out for you

This is typical of when the returned results is an HTML Body (error page, 404 not found, Accept header not set, etc) and not a JSON string as expected.

  1. Debug the res.getbody() and ensure it is a valid JSON string
  2. If not, see what the body is saying and fix it

You should add in some error handling to you code to catch this and handle as needed.

The following code works just fine in dev console:

HttpRequest req = new HttpRequest();

HttpResponse res = new HttpResponse();

Http http = new Http();

req.setEndpoint('http://www.itutorindia.com/angularjs/api/smallWidget/tutorHourSalesForce');

req.setMethod('GET');
req.setHeader('Content-Type', 'application/json');
req.setHeader('Accept','application/json');
res = http.send(req);

if(res.getstatusCode() == 200 && res.getbody() != null){
    system.debug(json.deserializeUntyped(res.getBody()));
}