As a follow up to this question:
I am essentially trying to deserialize a JSON object into an Interface Type.
Unfortunately we cannot deserialize using an Interface as the ApexType and must know the concrete class type to do so then cast to the interface....
As part of the interface there is a method to enforce returning the Name of the class but this only works when the Object is passed to aura and back to apex.
Using straight Apex when serializing the Class that implements the interface the property getter getName()
is not serialized and thus is null on deserialization into a Map<String,Object>
.
I am using the following method to get the class name from a class that implements the interface to be able to deserialize it:
/**
* Gets the Name property from a class
*
* @param objectJSON
*
* @return
*/
@TestVisible private static String getClassName(String objectJSON){
Map<String,Object> tmp = (Map<String, Object>) JSON.deserializeUntyped(objectJSON);
//Just for debugging purposes
for(String key : tmp.keySet()){
System.debug('Key: ' + key + ' - Value: ' + tmp.get(key));
}
String typeName = (String) ( (Map<String, Object>) JSON.deserializeUntyped(objectJSON) ).get('name');
System.debug('Type Name:' + typeName);
if(String.isBlank(typeName)){
throw new auraController_Exception('Well, this did not work as the name property was blank');
}
return typeName;
}
In the apex method I have a JSON serialized string of the class that implements the interface and I am trying to deserialize it into the interface type. The class name is unknown at this time and the interface requires a method getName()
to return the class name. This line calls the above method
theInterface controller = (theInterface) json.deserialize(objectJSON, Type.forName(getClassName(objectJSON)));
This works when the Class is serialized in Apex, sent to the aura controller, and sent back to Apex. The Name property is populated with the value. However, when Aura is taken out of the mix, the Apex serialization/deserialization of the class that implements the method always returns NULL when deserializing into the Map<String,Object>
and thus I am unable to perform the same thing in pure apex.
The class that implements the interface is as follows:
public with sharing class classThatImplements implements theInterface{
@AuraEnabled public static string getName(){
return 'classThatImplements';
}
}
So, is there a way to deserialize a JSON Serialized Class into an Interface Type when one does not know the name of the class?
I know I can:
- simply use get; set; //Not enforceable via an interface
- Use an abstract class //Does not really apply as there are many classes and external integrations that will implement the interface and the Name needs to be set in the concrete class.
- Just tell anyone who integrates that they need to do X. //Not desirable and is essentially what 1 and 2 would require
Maybe I am not explaining it well so please do as for clarification if needed.