Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Gson-反序列化不同类型_Java_Json_Gson - Fatal编程技术网

Java Gson-反序列化不同类型

Java Gson-反序列化不同类型,java,json,gson,Java,Json,Gson,我正在处理传入的JSON字符串,并希望使用GSON将它们反序列化为类型化的POJO对象。 但是,推送字符串的服务器可以发送不同类型的对象——尽管类型在JSON负载中定义 看看下面的两个JSON字符串,其中我有一个tradeEvent和一个errorEvent对象(还有其他5种类型,如settlementEvent、paymentEvent等) 我如何将其反序列化到GSON中的实际POJO(可能使用泛型),因为我直到运行时才知道类型——正如您可以看到的,第二级元素包含实际的对象类型(tradeEv

我正在处理传入的JSON字符串,并希望使用GSON将它们反序列化为类型化的POJO对象。 但是,推送字符串的服务器可以发送不同类型的对象——尽管类型在JSON负载中定义

看看下面的两个JSON字符串,其中我有一个tradeEvent和一个errorEvent对象(还有其他5种类型,如settlementEvent、paymentEvent等)

我如何将其反序列化到GSON中的实际POJO(可能使用泛型),因为我直到运行时才知道类型——正如您可以看到的,第二级元素包含实际的对象类型(tradeEvent、errorEvent等)

还应该添加-就POJO而言,我是否将第二个元素(即tradeEvent、errorEvent)表示为对象或字符串

 {
  "data": {
    "tradeEvent": {
      "tradeId": "2d28d464-a746-4c58-b19f-b586d2f5d015",
      "status": 2,
      "eventDescription": "Trade Settled"
    }
  }
}


{
  "data": {
    "errorEvent": {
      "Uuid": "3a36ae26-ba41-40d5-b11d-d8d842eb2356",
    "failureCode": 2, "tradeId": "2d28d464-a746-4c58-b19f-b586d2f5d015", "errorMessage": "Returned error: Exception while processing transaction: trade not matched"
    }
  }
}

感谢您的指导。

实现数据包装器类以提取事件对象可能是最简单的方法:

final class WrapperDto{
@可空
@SerializedName(“数据”)
@公开(序列化=假,反序列化=真)
私有最终数据到数据;
@抑制警告(“未使用”)
私有WrapperDto(@Nullable final DataDto data){
这个数据=数据;
}
@可空
E toEvent(){
如果(数据==null){
返回null;
}
返回data.toEvent();
}
私有静态最终类DataDto{
@可空
@SerializedName(“tradeEvent”)
@公开(序列化=假,反序列化=真)
私人最终活动。贸易活动;
@可空
@SerializedName(“errorEvent”)
@公开(序列化=假,反序列化=真)
私有最终事件。错误errorEvent;
@抑制警告(“未使用”)
私有DataDto(@Nullable final Event.Trade tradeEvent,@Nullable final Event.Error errorEvent){
this.tradeEvent=tradeEvent;
this.errorEvent=errorEvent;
}
@可空
私人E-toEvent()
抛出非法状态异常{
@可空
事件bestEvent=null;
for(最终事件:新事件[]{tradeEvent,errorEvent}){
如果(bestEvent==null){
最佳事件=事件;
}else if(事件!=null){
抛出新的IllegalStateException(“检测到歧义。event=“+event.getClass().getSimpleName()+”,bestEvent=“+bestEvent.getClass().getSimpleName());
}
}
@抑制警告(“未选中”)
最终E最佳事件=(E)最佳事件;
返回事件;
}
}
}
我认为,这种方法比适应您的需求更容易实施。但是,实现自定义类型适配器可能会在读取时检测到不明确的字段,因此不会对每个字段进行反序列化(这会花费更多的堆)

上述方法将通过以下测试:

private static final Gson Gson=new GsonBuilder()
.disableHtmlEscaping()
.excludeFieldsWithoutExposeAnnotation()
.create();
...
try(final JsonReader JsonReader=open(“tradeEvent.json”)){
assertTrue(gson.fromJson(jsonReader,WrapperDto.class).toEvent()instanceof Event.Trade);
}
try(final JsonReader JsonReader=open(“errorEvent.json”)){
assertTrue(gson.fromJson(jsonReader,WrapperDto.class).toEvent()instanceof Event.Error);
}
assertThrows(IllegalStateException.class,()->{
try(final JsonReader JsonReader=open(“tradeAndErrorEvent.json”)){
fromJson(jsonReader,WrapperDto.class).toEvent();
}
});