I've created a abstract class to allow for two-way serialization of JSON that has reserved keywords. There are definitely some limitations but it works for everything I've tried so far (google calendar & jira API).
/* Author: Charlie Jonas (charlie@callawaycloudconsulting.com)
* Description: Allows reserved named serialization.
* Usage: See Readme @ https://github.com/ChuckJonas/APEX-JSONReservedNameSerializer
*/
public abstract class JSONReservedSerializer {
private final Map<Type,Map<String,String>> typeMapKeys;
public JSONReservedSerializer(Map<Type, Map<String, String>> typeMapKeys){
this.typeMapKeys = typeMapKeys;
}
public String serialize(Object obj, System.Type type){
return serialize(obj, false, type);
}
public String serialize(Object obj, Boolean suppressNulls, System.Type type){
String retString = JSON.serialize(obj, suppressNulls);
retString = transformStringForSerilization(retString, typeMapKeys.get(type));
return retString;
}
public Object deserialize(String jsonString, System.Type type){
jsonString = transformStringForDeserilization(jsonString, typeMapKeys.get(type));
return JSON.deserialize(jsonString, type);
}
private static String transformStringForSerilization(String s, Map<String, String> mapKeys){
return replaceAll(s, mapKeys);
}
private static String transformStringForDeserilization(String s, Map<String, String> mapKeys){
Map<String,String> flippedMap = new Map<String,String>();
for(String key : mapKeys.keySet()){
flippedMap.put(mapKeys.get(key), key);
}
return replaceAll(s, flippedMap);
}
private static String replaceAll(String s, Map<String,String> toFromMap){
for(String key : toFromMap.keySet()){
s = s.replaceAll('"'+key+'"(\\ )*:', '"'+toFromMap.get(key)+'":');
}
return s;
}
}
Implementation looks like this:
public class MySerializer extends JSONImprovedSerializer {
private MySerializer() {
//setup mappings
super(new Map<Type,Map<String,String>>{
MyOuterDTO.class => OUTER_DTO_MAPPINGS
});
}
//define DTO's using mapped names
static final Map<String, String> OUTER_DTO_MAPPINGS = new Map<String, String> {
'obj' => 'object',
'isPrivate' => 'private'
};
public class OuterDTO {
public InnerDTO obj;
}
public class InnerDTO {
public Boolean isPrivate;
public String notReserved;
}
}
Usage (round trip serialization):
String origString = '{"object":{"private":true,"notReserved":"abc"}}';
//deserialization
MySerializer json = new MySerializer();
MySerializer.OuterDTO dto = (MySerializer.OuterDTO) json.deserialize(
origString,
MySerializer.OuterDTO.class
);
//serialization
String newString = json.serialize(obj);
System.assertEquals(origString, newString);
UPDATE
I Created a to a repo with install instruction using the sfdx-cli