I have a set of classes with following structure
public abstract class Rule { .... }
public class RuleType1 extends Rule { ... }
public class RuleType2 extends Rule { ... }
public class RuleType3 extends Rule { ... }
public class RuleType4 extends Rule { ... }
public class RuleSet extends Rule {
...
private final Collection<Rule> rules;
}
I want to parse following json, which contains multiple nested Rule
child classes. Since RuleSet
contains Collection
of Rule
, it can have multiple RuleSet
as well.
I have checked these answers already. I don't want to implement custom (de)serializer because that will make child classes less flexible. (Whoever will change classes will need to change serializer classes as well)
Deserializing an abstract class in Gson
Gson serialize a list of polymorphic objects
Here is the same json, I want to serialize/deserialize.
{
"ruleType": "ruleSet",
"rules": [
{
"ruleType": "ruleSet",
"rules": [
{
"ruleType": "RuleType1"
},
{
"ruleType": "ruleSet",
"rules": [
{
"ruleType": "RuleType2"
},
{
"ruleType": "RuleType3"
}
]
}
]
},
{
"ruleType": "ruleSet",
"rules": [
{
"ruleType": "RuleType1"
},
{
"ruleType": "ruleSet",
"rules": [
{
"ruleType": "RuleType3"
},
{
"ruleType": "RuleType4"
}
]
}
]
}
]
}
Edit after comments:
This is my class structure where
RuleSet
has Collection<IRule> rules
And this is my class
public class SampleClass {
public IRule parameters;
public double defaultConfidence;
public String ruleType;
}
static RuntimeTypeAdapterFactory<IRule> adaptor = RuntimeTypeAdapterFactory.of(IRule.class)
.registerSubtype(RuleSet.class)
.registerSubtype(Rule.class);
static RuntimeTypeAdapterFactory<Rule> ruleAdaptor = RuntimeTypeAdapterFactory.of(Rule.class)
.registerSubtype(DocumentTypesRule.class)
.registerSubtype(DataAttributesRule.class)
.registerSubtype(DictionariesRule.class)
.registerSubtype(FileFormatsRule.class)
.registerSubtype(FileLengthRule.class)
.registerSubtype(FileNamePatternsRule.class)
.registerSubtype(FixedRule.class)
.registerSubtype(ImageTypesRule.class)
.registerSubtype(KeywordsRule.class)
.registerSubtype(RegexesRule.class)
.registerSubtype(SimilaritiesRule.class)
.registerSubtype(TopicsRule.class);
private static final Gson GSON = new GsonBuilder()
.registerTypeAdapterFactory(adaptor)
.registerTypeAdapterFactory(ruleAdaptor)
.create();
and facing following error while calling GSON.fromJson(response, SampleClass.class)
java.lang.RuntimeException: Unable to invoke no-args constructor for interface <classPath>.IRule. Registering an InstanceCreator with Gson for this type may fix this problem.