我有一个简单的Json结构,比如:
{"MessageType":"TimeData","TimeData":{"hh":12,"mm":13,"ms":15,"ss":14}}
我设计了以下类来反序列化它:
public class JsonMessage
{
public enum MessageTypes{
WhoAreYou,
TimeData
}
JsonMessage(){
}
public MessageTypes MessageType;
}
class TimeData extends JsonMessage{
int hh;
int mm;
int ss;
int ms;
TimeData() {
}
}
我需要将反序列化分为两个阶段:
1-反序列化以读取消息类型
。
2.2基于MessageType进行其余的反序列化
代码很简单:
public void dispatch(Object message, IoSession session)
{
Gson gson = new Gson();
JsonMessage result = gson.fromJson(message.toString(), JsonMessage.class);
System.out.println(result.MessageType.toString());
switch (result.MessageType)
{
case WhoAreYou:{
//.....
break;
}
case TimeUpdate:
TimeData res = new Gson().fromJson(message.toString(), TimeData.class);
System.out.println(res.hh);
break;
default:break;
}
}
我的程序可以输入正确的Switch-case
(即TimeUpdate
),但它不能正确解析它(println打印0而不是12)
你觉得我哪里做错了?谢谢你们
我通过以下方式实现了一个定制的JsonDeserializer
,成功地解决了类似的问题。
首先,根据类型和检索正确类的方法将子类附加到枚举中
enum MessageType {
WHO_ARE_YOU(WhoAreYou.class),
TIME_UPDATE(TimeUpdate.class);
public final Class<?> clazz;
MessageType(Class<?> clazz) { this.clazz = clazz; }
public static MessageType forName(String name) {
for (MessageType t : values())
if (name.equals(t.name()))
return t;
return NULL;
}
}
然后在
反序列化
方法中,我执行了以下操作:
public JsonMessage deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
JsonObject object = json.getAsJsonObject();
String kind = object.get("messageType").getAsString();
Class<?> clazz = MessageType.forName(kind).clazz;
JsonMessage result = null;
try {
result = (JsonMessage)clazz.newInstance();
Field[] fs = clazz.getFields();
for (Field f : fs) {
Object value = context.deserialize(object.get(f.getName()), f.getType());
if (value != null)
f.set(result, value);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
一切都通过反射来管理,以便创建正确的对象,然后相应地反序列化所有字段。
我有一个复杂的对象层次结构,所以我更喜欢这样做,让gson反序列化程序管理一切。当然,您需要向gson解析器实例注册序列化程序。
注意:根据Java标准,你对事物的命名是非常不正确的。枚举常量应该是
ALL_CAPITALIZED
,枚举类名应该是单数的(例如。MessageType
)。实例变量应该被骆驼(例如。MessageType
而不是MessageType
)
问题是,JSON表示的对象包含您感兴趣的另一个对象,而Java只是一个对象。
实际上,您可以为每种类型编写反序列化程序,并在确定消息类型后使用它们:
public static void main(String[] args)
{
Gson gson = new GsonBuilder().registerTypeAdapter(TimeData.class, new TimeDataDeserializer()).create();
String json = "{\"MessageType\":\"TimeData\",\"TimeData\":{\"hh\":12,\"mm\":13,\"ms\":15,\"ss\":14}}";
JsonMessage message = gson.fromJson(json, JsonMessage.class);
switch(message.MessageType)
{
case TimeData:
TimeData td = new GsonBuilder()
.registerTypeAdapter(TimeData.class, new TimeDataDeserializer())
.create()
.fromJson(json, TimeData.class);
td.MessageType = message.MessageType
System.out.println(td.hh);
break;
default:
break;
}
}
class TimeDataDeserializer implements JsonDeserializer<TimeData>
{
@Override
public TimeData deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
JsonObject jo = je.getAsJsonObject().getAsJsonObject("TimeData");
Gson g = new Gson();
return g.fromJson(jo, TimeData.class);
}
}
在Android应用程序中,我需要用一个抽象级别反序列化Kotlin数据类的Json数据。但我不知道如何在构造函数中放置正确的属性。 简单来说,假设我有一个形状: 有两个派生 和 所以我的目标是,不要实例化一个形状。所以,相反,总是反序列化它的派生。稍后,我需要处理其他类中的一些集合属性,如: 但我还必须知道每个元素的派生类型。 当我尝试用Gson反序列化给定的示例时 我总是有一个非法的辩论例外
解决了。 我在另一个类中初始化我的产品列表: 我想做的是,在构造函数中初始化我的产品列表,如下所示: 这是我的方法,它将对象列表写入。json文件: 我在成员的帮助下找到的解决方案: 和构造函数:
问题:类A实现可序列化类B扩展了类A实现可序列化 现在我只使用类B作为运行时类型进行序列化。所以我有一个列表: 如果我现在反序列化它,我就得到了java。伊奥。OptionalDataException错误。我想知道的是,我的对象如何成为正确的运行时类型。反序列化: 如果在序列化时是类B的运行时类型,这是否会导致类B的运行时类型,或者我必须覆盖A的earch子类的默认序列化? 希望我没有错过任何明
问题内容: 我想通过Google Gson传输列表对象,但是我不知道如何反序列化泛型类型。 看了这个之后我尝试了什么(BalusC的答案): 但是后来我在日食中遇到了一个错误,说“新的List(){}类型必须实现继承的抽象方法…”,如果我使用快速修复方法,则会得到20个以上的方法存根的怪物。 我很确定有一个更简单的解决方案,但是我似乎找不到它! 编辑: 我现在有 但是,我确实在“ fromJson
问题内容: 由于要执行处理的业务逻辑,因此我正在实现自定义。但是某些部分可以解析为标准方式。这是否可能- 我自己处理一些元素,并让一些嵌套元素自动处理? 这是JSON: 这是项的自定义反序列化器: 现在,我想让GSON解析枚举。我可以自己完成,这只是几行代码,但是我更愿意库做很多。 问题答案: …但是我希望图书馆尽其所能。 好吧,只需使用Gson。 有数据传输对象模式,尤其是Gson映射类,可以完
假设我有一组a、B、C类: 公开A类:整数; 公共B类:整数;字符串地址; 公共类C:int orderNumber; 如何反序列化仅包含这些类但顺序未知的Json字符串(在Java中使用Gson)?例如: 非常感谢你!