如果,一个类嵌套太深,有很多子类,这样进行反序列化时,会出现一些反序列化异常(如会报一些构造无参数的异常)。 如下图BasNode有下列子类,
这是什么原因呐?
仔细想下:反序列化时都是按父类往下构建的,但是json字符串中是子类的序列化数据,这样直接去反序列化肯定是不行的。
用 GsonBuilder配合 JsonDeserializer能完美解决这一问题
/**
* 数组转对象
* @param bytes
* @return
*/
public static Object toObject (byte[] bytes,Class<?> aClass) {
String s = new String(bytes);
Gson gson = new GsonBuilder()
.registerTypeAdapter(BaseNode.class, new NodeJsonDeserializer())
.registerTypeAdapter(Variable.class, new VariableJsonDeserializer())
.create();
return gson.fromJson(s, aClass);
}
/**
* Created by xzs on 2020/9/2.
*/
public class NodeJsonDeserializer implements JsonDeserializer<BaseNode> {
@Override
public BaseNode deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String type = json.getAsJsonObject().get("nodeType").getAsString();
switch(type) {
case"ROOT":
return context.deserialize(json, RootNode.class);
case"SINGLECOLLECTION":
return context.deserialize(json, SingleCollectionNode.class);
case"MULTICOLLECTION":
return context.deserialize(json, MultiCollectionNode.class);
case"TIMEASSERT":
return context.deserialize(json, DateAssertNode.class);
case"ANIASSERT":
return context.deserialize(json, AniAssertNode.class);
case"DNISASSERT":
return context.deserialize(json, DnisAssertNode.class);
case"VARIABLEASSERT":
return context.deserialize(json, VariableAssertNode.class);
case"TRANSFERVDN":
return context.deserialize(json, TransferVdnNode.class);
case"TRANSFERFLOW":
return context.deserialize(json, TransferFlowNode.class);
case"HANGUP":
return context.deserialize(json, HungupNode.class);
case"PLAYBACK":
return context.deserialize(json, PlayMediaNode.class);
case"VARIABLESETNODE":
return context.deserialize(json, VariableSetNode.class);
case"FEEDBACK":
return context.deserialize(json, FeedBackNode.class);
case"DMENU":
return context.deserialize(json, DmenuNode.class);
case"OPTIONALMENU":
return context.deserialize(json, OptionalMenuNode.class);
case"API":
return context.deserialize(json, ApiRouterAssertNode.class);
case"UUIANALYTIC":
return context.deserialize(json, UuiAnalyticNode.class);
default:
throw new IllegalArgumentException(String.format("deserialize BaseNode type(%s) is empty",type));
}
}
}