解析动态包装的JSON数组

时间:2017-04-12 04:02:19

标签: java json jackson

我有一个包含许多具体实现的Abstract类:

public abstract Ticket {
   private Long id;
   private Currency fine;
   ...
}

public class SpeedingTicket extends Ticket {
   public Currency getFine(){
      // Expensive!
      ...
   }
}

public class ParkingTicket  extends Ticket {
   public Currency getFine(){
      // Eh, not so bad
      ...
   }
}

当具体类被序列化为JSON时,它将使用类简单名称(speedingTickets或parkingTickets)包装:

"_embedded": {
   "speedingTickets" :
    [{
      "id":1,
      "fine": "$190",
       ...,
    },
    {
      "id":2,
      "fine": "$100",
       ...,
    }]
}

"_embedded": {
   "parkingTickets" :[{
      "id":100,
      "fine": "$15",
       ...,
    }]
}

由于我不知道,在运行时,我收到了哪个Ticket实现,如何使用JSON Response API解析JSON,因为数组包含了具体的实现简单命名

我有一个hack,我在其中获取JSON的String值并对其执行String操作(substring,indexOf等)以仅返回大括号之间的内容(“[...]”)。我知道有更好的方法来做到这一点......


经过一些研究,我想我明天会尝试以下方法,看它是否有效:

JsonNode rootNode = mapper.readTree(jsonResponse);
String classImpl = Iterables.get(rootNode.get("_embedded").fields(), 0).textValue()

然后我可以说List<Ticket> tickets = response.readAsList(jsonResponse, "_embedded",classImpl)这应该允许我将JSON解析为List

3 个答案:

答案 0 :(得分:0)

如果你正在使用Jackson(正如你的标签所示),你想使用Polymorphic Deserialization - 这正是知道如何反序列化到正确的子类型的问题。

例如:

 @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
 class  { } 

这基本上做的是在JSON中包含类名,因此反序列化器有足够的信息来正确选择要实例化的子类。像这样:

"_embedded": {
   "parkingTickets" :[{
      "_type": "ParkingTicket.class",
      "id":100,
      "fine": "$15",
       ...,
    }]
}

答案 1 :(得分:0)

您可以通过检查响应包含的变量来检查类型。

JSONObject jsonObj = new JSONObject(response);
if(jsonObj.has("speedingTickets")){
    // parse speedingTickets
}else if(jsonObj.has("parkingTickets")){
    // parse parkingtickets
}

答案 2 :(得分:-1)

JSON对象是一组无序的键/值对。 JSON数组是有序的值集合。值本身可以是对象或数组。

在java中,使用org.json库https://github.com/stleary/JSON-java

解析json很容易

如何解析json数组的简短示例:

String str = "{ \"number\": [3, 4, 5, 6] }";
JSONObject obj = new JSONObject(str);
JSONArray arr = obj.getJSONArray("number");
for (int i = 0; i < arr.length(); i++)
    System.out.println(arr.getInt(i));