Handling JSON in Apex

advertisement
Handling JSON in Apex
Shamil Arsunukayev
Technical Architect, Comity Designs Inc.
@shamiltech
Agenda
System.JSON
System.JSONGenerator
System.JSONParser
Demo: Google Calendar APIs + JSON + Apex
Q&A
System.JSON
JSON.serialize:
Account acctOne = [SELECT id, name FROM Account LIMIT 1];
String acctJSON = JSON.serialize(acctOne);
JSON.deserialize:
Account acctTwo = (Account) JSON.deserialize(acctJSON,
Account.class);
Minimum number of script statements
No need to use Dynamic Apex to inspect the
metadata, it’s all automatic!
CalendarList Resource JSON
{
"kind": "calendar#calendarListEntry",
"etag": etag,
"id": string,
"summary": string,
"hidden": boolean,
…
"defaultReminders": [
{
"method": string,
"minutes": integer
}
]
GoogleCalendar Apex Class
public class GoogleCalendar {
public String id;
public String kind;
public String etag;
public String summary;
public Boolean hidden;
…
public List<GoogleReminderOverride>
defaultReminders;
}
System.JSON
public String serialize() {
return JSON.serialize(this);
}
public void deserialize(String jsonString) {
GoogleCalendar gCal = (GoogleCalendar)
JSON.deserialize(jsonString, GoogleCalendar.class);
…
}
Notice how Apex objects are used instead of sObjects
System.JSON
Note: If GoogleCalendar Apex class didn’t have a
field or fields to match the CalendarList JSON
structure, the JSON.deserialize() method would
have failed with the “System.JSONException:
Unknown field field_name “ exception
JSONGenerator
 Contains methods used to serialize Apex objects into JSON content
using the standard JSON encoding.
 Useful for wrapping or aggregating values
 Can be used instead of the JSON.serialize() if the latter could
not be used
List<Contact> contacts = [Select Id, Name From Contact];
generator.writeStartObject();
generator.writeNumberField(‘count’, contacts.size());
generator.writeEndObject();
String jsonString = generator.getAsString();
Event Resource JSON
{
“summary": string,
“end": {
"date": date,
…
},
"attendees": [
{ "email": string,
…
}
],
"reminders": {
"useDefault": boolean,
"overrides": [
{ "method": string,
"minutes": integer
}
]
}
<-------- ‘end’ is a reserved Apex keyword
<-------- ‘date’ is a reserved Apex keyword
GoogleCalendarEvent Apex Class
public class GoogleCalendarEvent {
public String summary;
…
public GoogleEventTime start;
public GoogleEventTime gEnd; //renamed ‘end’
public List<GoogleEventAttendee> attendees;
public GoogleReminder reminders;
}
JSONGenerator
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeStringField('summary', ‘New event’);
gen.writeFieldName('start');
gen.writeStartObject();
gen.writeObjectField('dateTime', System.now().addDays(1));
//or gen. writeDateTimeField('dateTime', System.now().addDays(1));
gen.writeEndObject();
{
“summary”: “New event",
"start": {
"dateTime": "2012-03-16T18:03:32-08:00“
},
JSONGenerator
gen.writeFieldName('reminders');
gen.writeObject(reminders); //reminders is a GoogleReminder object
…
"reminders": {
"useDefault": false,
"overrides": [
{ "method": "email",
"minutes": 1 },
{ "method": "email",
"minutes": 2 }
]
}…
GoogleReminder Apex Class
public class GoogleReminder {
public Boolean useDefault;
public List<GoogleReminderOverride> overrides;
}
public class GoogleReminderOverride {
public String method;
public Integer minutes;
}
JSONGenerator
gen.writeFieldName('attendees');
gen.writeStartArray();
for(GoogleEventAttendee gEventAttendee: this.attendees){
gen.writeStartObject();
gen.writeStringField('email', gEventAttendee.email);
gen.writeBooleanField('optional', gEventAttendee.optional);
gen.writeNumberField('additionalGuests',
gEventAttendee.additionalGuests);
gen.writeEndObject();
}
gen.writeEndArray();
…
String jsonString = gen.getAsString(); //create a JSON string
JSONGenerator
"attendees": [
{
"email": "attendeeOne@gmail.com",
"optional": false,
"additionalGuests": 1
},
{
"email": "attendeeTwo@gmail.com",
"optional": true,
"additionalGuests": 2
},
...
]
JSONParser
 Generally, JSONParser is useful for grabbing specific pieces of
data without the need for a structure such as an Apex class
JSONParser parser = JSON.createParser(resp);
while (parser.nextToken() != null) {
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)){
String fieldName = parser.getText();
parser.nextToken();
if(fieldName == 'access_token') {
accesstoken = parser.getText();
} else if(fieldName == 'expires_in'){
expiresIn = parser.getIntegerValue();
}
}}
JSONParser
"attendees": [
{
"email": "attendeeOne@gmail.com",
"optional": false,
"additionalGuests": 1
},
{
"email": "attendeeTwo@gmail.com",
"optional": true,
"additionalGuests": 2
},
...
]
JSONParser
…
if(fieldName == 'attendees'){
if(parser.getCurrentToken() == JSONToken.START_ARRAY){
while(parser.nextToken() != null){
if(parser.getCurrentToken() == JSONToken.START_OBJECT){
GoogleEventAttendee gEventAttendee =
(GoogleEventAttendee)
parser.readValueAs(GoogleEventAttendee.class);
this.attendees.add(gEventAttendee);
}
else if(parser.getCurrentToken() == JSONToken.END_ARRAY){
break;
}}}}
Demo: Google Calendar
APIs + JSON + Apex
Thank you
Questions & Answers
Download