我的jsons包含任何类型的消息,json包含一个String,指出消息的类型。
我想反序列化它们并获得1.表示消息的消息类型实例和2.主题的实例,其中T是消息类型。
例如:
INPUT1
{
"messageType":"String",
"message": "a string"
}
我希望反序列化后的结果与手工完成的结果相同:
Topic<String> t = new Topic<String>(String.class);
String message = "a string";
输入2
{
"messageType":"Integer",
"message": 1
}
我希望反序列化后的结果与手工完成的结果相同:
Topic<Integer> t = new Topic<Integer>(Integer.class);
Integer message = 1;
输入3
{
"messageType":"MyClass",
"message": {"a": "something", "b": 1}
}
我希望反序列化后的结果与手工完成的结果相同:
Topic<MyClass> t = new Topic<MyClass>(MyClass.class);
MyClass message = new MyClass("something", 1);
INPUT4
... same with other types ...
我认为你明白了。但现在我需要以通用/抽象的方式以某种方式做到这一点。我尝试了这个,但这不起作用:
private enum MessageType {
STRING(String.class), INTEGER(Integer.class), BOOLEAN(Boolean.class), MYCLASS(MyClass.class);
private Class<?> clazz;
MessageType(Class<?> clazz) {
this.clazz = clazz;
}
}
private static class MyJson {
String topicId;
String messageType;
Object message;
}
MyJson<?> myJson = gson.fromJson(input, MyJson.class);
MessageType type = MessageType.valueOf(myJson.messageType);
Class<?> clazz = type.getClass();
??? message = clazz.newInstance(message);
Topic<???> t = new ?????
我不知道该怎么办?!我需要主题和消息类型,但如何???以下似乎很糟糕:
@SuppressWarnings("unchecked")
private <T> Topic<T> createTopic(Class<T> typeClass) {
try {
return Topic.class.getConstructor(typeClass).newInstance(typeClass);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Fail");
}
}
答案 0 :(得分:0)
现在对我有用:
class Topic<MessageType> {
// ...
public Class<MessageType> getMessageTypeClass() // ...
// ...
}
解析结果数据struct:
public class TopicLine {
public Topic<?> topic;
public Object message;
}
解串器:
public class MessageDeserializer implements JsonDeserializer<TopicLine> {
private static class InternalParseLine {
String messageType;
JsonElement message;
}
private Map<String, Topic<?>> messageTypes = new HashMap<String, Topic<?>>();
public MessageDeserializer() {
messageTypes.put("Integer", new Topic<Integer>(Integer.class));
// other topics
}
private static class InternalParseLine {
String topicId;
JsonElement message;
}
@Override
public TopicLine deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
InternalParseLine line = context.deserialize(json, InternalParseLine.class);
TopicLine topicLine = new TopicLine();
topicLine.topic = topics.get(line.messageType);
topicLine.message = context.deserialize(line.message, topicLine.topic.getMessageTypeClass());
return topicLine;
}
}
用法:
json = new GsonBuilder()
.registerTypeAdapter(TopicLine.class, new TopicLineDeserializer())
.create();
TopicLine t = json.fromJson(line, TopicLine.class);
事实上,为了使它更具动态性,我使用了一个topic-manager,它在构造函数中传递给反序列化器而不是静态映射。所以我可以在运行时动态注册和取消注册主题/消息类型。