In Apex, certain words are reserved and cannot be used as identifiers, such as variable or property names. This creates a challenge when trying to deserialize JSON that contains these reserved words as property names. For instance:
String jsonString = '{"currency" : "ABC"}';
public class JSONResult {
public String currency;
}
// Attempting to deserialize
JSONResult res = (JSONResult) JSON.deserialize(jsonString, JSONResult.class);
System.debug(res);
The above code results in an error because currency
is a reserved word in Apex. There are two common ways to address this issue, along with an advanced solution using a custom serializer/deserializer:
1. String Replacement in the JSON String
One straightforward solution is to replace the reserved word in the JSON string with a non-reserved substitute before deserialization. After processing, you can replace it back if necessary. For example:
String jsonString = '{"currency" : "ABC"}';
jsonString = jsonString.replace('"currency":', '"currency_x":');
public class JSONResult {
public String currency_x;
}
JSONResult res = (JSONResult) JSON.deserialize(jsonString, JSONResult.class);
System.debug(res.currency_x); // Outputs: ABC
In this code, the reserved keyword currency
is replaced with currency_x
in the JSON string, and the JSONResult
class defines a matching property. This allows successful deserialization, avoiding reserved word conflicts. The debug statement prints the deserialized value of the currency_x
property.
2. Manually Parsing JSON with JSONParser
Another approach is to use the JSONParser
class to manually parse the JSON string and map reserved words to acceptable identifiers. While this method is accurate and flexible, it requires more effort and can be tedious if the JSON structure changes frequently.
String jsonString = '{"currency" : "ABC"}';
JSONParser parser = JSON.createParser(jsonString);
String currencyValue;
while (parser.nextToken() != null) {
if (parser.getCurrentToken() == JSONToken.FIELD_NAME && parser.getText() == 'currency') {
parser.nextToken();
currencyValue = parser.getText();
}
}
System.debug(currencyValue); // Outputs: ABC
Here, the JSONParser
is used to process the JSON string token by token. When the parser encounters the currency
field, it retrieves the associated value. This avoids deserialization errors related to reserved words while maintaining full control over the parsing logic.
3. Using a Custom Serializer/Deserializer
For a more robust solution, you can implement a custom serialization and deserialization framework that maps reserved keywords to alternative names during processing. Here’s an example based on the implementation by Charlie Jonas:
Custom Abstract Class:
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) {
String retString = JSON.serialize(obj);
return transformForSerialization(retString, typeMapKeys.get(type));
}
public Object deserialize(String jsonString, System.Type type) {
jsonString = transformForDeserialization(jsonString, typeMapKeys.get(type));
return JSON.deserialize(jsonString, type);
}
private static String transformForSerialization(String s, Map<String, String> mapKeys) {
for (String key : mapKeys.keySet()) {
s = s.replaceAll('"' + key + '"(\\s*):', '"' + mapKeys.get(key) + '":');
}
return s;
}
private static String transformForDeserialization(String s, Map<String, String> mapKeys) {
Map<String, String> reversedMap = new Map<String, String>();
for (String key : mapKeys.keySet()) {
reversedMap.put(mapKeys.get(key), key);
}
return transformForSerialization(s, reversedMap);
}
}
In this abstract class, mappings between reserved keywords and alternative names are maintained in a map. The transformForSerialization
and transformForDeserialization
methods handle bidirectional replacements, ensuring reserved words are appropriately substituted during serialization and deserialization.
Implementation:
public class MySerializer extends JSONReservedSerializer {
private static final Map<String, String> MAPPINGS = new Map<String, String> {
'currency' => 'currency_alias'
};
public MySerializer() {
super(new Map<Type, Map<String, String>> {
JSONResult.class => MAPPINGS
});
}
public class JSONResult {
public String currency_alias;
}
}
String jsonString = '{"currency" : "ABC"}';
MySerializer serializer = new MySerializer();
MySerializer.JSONResult res = (MySerializer.JSONResult) serializer.deserialize(jsonString, MySerializer.JSONResult.class);
System.debug(res.currency_alias); // Outputs: ABC
This implementation defines a custom serializer and a mapping for reserved words. The JSONReservedSerializer
class substitutes currency
with currency_alias
during deserialization. The mapped property is then accessed without any errors, making it suitable for handling APIs or JSON with reserved keywords.
Summing Up
To handle reserved words in JSON deserialization in Apex, you have three main options:
- String Replacement: Replace reserved words in the JSON string with acceptable alternatives before deserialization. This is simple but risky if unintended replacements occur.
- Manual Parsing with
JSONParser
: Use Apex’sJSONParser
to manually extract and process data, ensuring full control over reserved word handling but requiring more effort for complex structures. - Custom Serializer/Deserializer: Implement a custom serialization framework to map reserved keywords to alternative identifiers. This robust solution works well for APIs with consistent structures but involves an initial setup effort.
Each approach has trade-offs, and the best choice depends on the complexity of your JSON and your use case.
Our Salesforce training in India provides comprehensive learning with practical exposure to real-world projects and expert guidance. Designed for all skill levels, this course equips you with the expertise to excel in Salesforce CRM. Enroll today and take the first step toward a successful career in Salesforce!
The post How to Handle Reserved Words in JSON Deserialization? appeared first on Salesforce Online Training.