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

我正在使用Retrofit来获取JSON答复。

这是我实施的一部分-

@GET("/api/report/list")
Observable<Bills> listBill(@Query("employee_id") String employeeID);

而条例草案类是-

public static class Bills {
    @SerializedName("report")
    public ArrayList<BillItem> billItems;
}

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;
}

问题是有时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"
      }
   ]
}

但是,有时响应是这样的,它给出了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"
      }
   }
}

如何处理这样的答复?

java大神给出的解决方案

使用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;
     }
}

请参见示例:Gson deserialization - Trying to parse a JSON to an Object

java.net.URI.create异常 - java

java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…

如何在Java中以语言环境正确的顺序格式化日期和月份? - java

有没有一种方法可以用Java / Kotlin中的区域设置正确的格式格式化日和月(以紧凑格式)而不格式化年份?因此,对于英语,应为“ 9月20日”,而对于瑞典语为“ 9月20日”。为了进行比较,在Cocoa平台上,我可以执行以下操作(在Swift中):let formatter = DateFormatter() formatter.locale = Loc…

如何在JAVA中传递以逗号分隔的值作为函数参数的字符串 - java

我有一个可以接受任何数量的INTEGER参数的方法:pages(int,int...)此方法是选择PDF文件的某些页面。以以下字符串类型存储的书页:String pages = "1,2,3,6,9"; 我想将此字符串作为方法的参数看起来像:pages(1,2,3,6,9); java大神给出的解决方案 使用流可以很容易地做到这一点:St…

DataSourceTransactionManager和JndiObjectFactoryBean和JdbcTemplate的用途是什么? - java

以下的用途是什么:org.springframework.jdbc.core.JdbcTemplate org.springframework.jdbc.datasource.DataSourceTransactionManager org.springframework.jndi.JndiObjectFactoryBean <tx:annotatio…

唯一约束未对Hibernate的SchemaExport强制执行 - java

我很不确定为什么我的实体类没有创建我所需的表架构@Entity @Table(name = "User") public class User implements Serializable { private Long id; private String loginName; @Id @GeneratedValue public Lo…