当回复有时是一个对象而有时是一个数组时,如何在使用改进时解析JSON回复?

yad*_*_vi 2 java json rx-java retrofit

我正在使用Retrofit来获取JSON回复.

以下是我实施的部分内容 -

@GET("/api/report/list")
Observable<Bills> listBill(@Query("employee_id") String employeeID);
Run Code Online (Sandbox Code Playgroud)

班级比尔是 -

public static class Bills {
    @SerializedName("report")
    public ArrayList<BillItem> billItems;
}
Run Code Online (Sandbox Code Playgroud)

BillItem班是如下-

public static class BillItem {
    @SerializedName("id")
    Integer entryID;
    @SerializedName("employee_id")
    Integer employeeDBID;
    @SerializedName("type")
    String type;
    @SerializedName("subtype")
    String subtype;
    @SerializedName("date")
    String date;
    @SerializedName("to")
    String to;
    @SerializedName("from")
    String from;
    @SerializedName("amount")
    Double amount;
    @SerializedName("location")
    String location;
    @SerializedName("remark")
    String remark;
    @SerializedName("ispaid")
    String isPaid;
    @SerializedName("created_at")
    String createdAt;
    @SerializedName("updated_at")
    String updateAt;
}
Run Code Online (Sandbox Code Playgroud)

问题是REST API有时会返回一个BillItem对象数组,但有时它只是一key-value对.如何处理这种情况?

收到此响应后,一切正常,因为JSONArray获取映射到ArrayList<BillItem>-

{
   "emp":{
      "id":41,
      "name":"",
      "email":"",
      "created_at":"2016-02-01 10:36:38",
      "updated_at":"2016-02-01 10:36:38"
   },
   "report":[
      {
     "id":175,
     "employee_id":41,
     "type":"Travel",
     "subtype":"Car",
     "date":"2016-02-02 00:00:00",
     "to":"gaha",
     "from":"hshsj",
     "amount":"64",
     "location":"",
     "remark":"shhs",
     "ispaid":false,
     "created_at":"2016-02-01 13:52:52",
     "updated_at":"2016-02-01 13:52:52"
      },
      {
     "id":179,
     "employee_id":41,
     "type":"Travel",
     "subtype":"Car",
     "date":"2016-02-01 00:00:00",
     "to":"Gsh",
     "from":"Dgdh",
     "amount":"7646",
     "location":"",
     "remark":"Shsh",
     "ispaid":false,
     "created_at":"2016-02-01 14:39:48",
     "updated_at":"2016-02-01 14:39:48"
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

但是,有时响应是这样的,它给出了JsonSyntaxException-

{
   "emp":{
      "id":41,
      "name":"",
      "email":"",
      "created_at":"2016-02-01 10:36:38",
      "updated_at":"2016-02-01 10:36:38"
   },
   "report":{
      "1":{
     "id":175,
     "employee_id":41,
     "type":"Travel",
     "subtype":"Car",
     "date":"2016-02-02 00:00:00",
     "to":"gaha",
     "from":"hshsj",
     "amount":"64",
     "location":"",
     "remark":"shhs",
     "ispaid":false,
     "created_at":"2016-02-01 13:52:52",
     "updated_at":"2016-02-01 13:52:52"
      },
      "2":{
     "id":179,
     "employee_id":41,
     "type":"Travel",
     "subtype":"Car",":"2016-02-01 00:00:00",
     "to":"Gsh",
     "from":"Dgdh",
     "amount":"7646",
     "location":"",
     "remark":"Shsh",
     "ispaid":false,
     "created_at":"2016-02-01 14:39:48",
     "updated_at":"2016-02-01 14:39:48"
      },
      "0":{
     "id":181,
     "employee_id":41,
     "type":"Travel",
     "subtype":"Car",
     "date":"2016-02-01 00:00:00",
     "to":"ggg",
     "from":"vg",
     "amount":"0",
     "location":"",
     "remark":"cvv",
     "ispaid":false,
     "created_at":"2016-02-01 17:43:43",
     "updated_at":"2016-02-01 17:43:43"
      },
      "3":{
     "id":182,
     "employee_id":41,
     "type":"Travel",
     "subtype":"Car",
     "date":"2016-02-01 00:00:00",
     "to":"Haha",
     "from":"Ahah",
     "amount":"0",
     "location":"",
     "remark":"Ahah",
     "ispaid":false,
     "created_at":"2016-02-01 17:53:58",
     "updated_at":"2016-02-01 17:53:58"
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

如何处理这样的回复?

Gav*_*iel 6

当您使用Gson反序列化器时,您可以检查JsonElement中的类型:

Gson gson = new GsonBuilder()
            .registerTypeAdapter(BillItem.class, new BillItemDeserializer())
            .registerTypeAdapter(Bills.class, new BillsDeserializer())
            .create();

RestAdapter.Builder builder = new RestAdapter.Builder()
            //...
            .setConverter(new GsonConverter(gson));

public class BillsDeserializer implements JsonDeserializer<StringList> {

    public Bills deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {
         BillItemList value = new BillItemList();
         if (json.isJsonArray()) {
             for (JsonElement element : json.getAsJsonArray()) {
                 value.add(gson.fromJson(element, BillItem.class));
             }
         } else {
             value.add(gson.fromJson(element, BillItem.class));
         }
         return value;
     }
}
Run Code Online (Sandbox Code Playgroud)

请参阅示例:Gson反序列化 - 尝试将JSON解析为Object