关于 Gson 解析 json 数据

2019-04-28 23:35:56 +08:00
 Nitroethane

现有服务端返回的数据格式如下:

{
  "success": true,
  "data": [
    {
      "label": "高清频道",
      "id": 1,
      "expanded": false,
      "children": [
        {
          "label": "CCTV1 综合高清",
          "id": 1,
          "actionUrl": "/tv-show-detail/1",
          "imgUrl": "/cover/tv/1.jpg",
          "current": {
            "name": "瞬间中国",
            "time": "15:15-15:23"
          }
         },
        {
          "label": "CCTV2 财经高清",
          "id": 2,
          "actionUrl": "/tv-show-detail/2",
          "imgUrl": "/cover/tv/2.jpg",
          "current": {
            "name": "周末特供",
            "time": "15:20-15:42"
          }
         },
        {
          "label": "BTV6 体育高清",
          "id": 19,
          "actionUrl": "/tv-show-detail/19",
          "imgUrl": "/cover/tv/19.jpg",
          "current": false
         }
       ]
     }
   ]
}

children 字段里元素对应的类的定义为(使用的 Retrofit 和 Gson ):

public class Channel {
    @SerializedName("label")
    private String label;
    @SerializedName("id")
    private int id;
    @SerializedName("actionUrl")
    private String actionUrl;
    @SerializedName("imgUrl")
    private String imgUrl;
    @SerializedName("current")
    private CurrentShow current;
    ......

CurrentShow 是我定义的用来解析 current 字段的:

public class CurrentShow {
    private String name;
    private String time;
    private boolean empty;
    ...

现在的问题是,如果 current 字段为空的话值是 false,否则是 nametime 字段,所以上面这个 CurrentShow 用来处理 current 字段是有问题的。这个应该怎么处理呢?

6762 次点击
所在节点    Android
26 条回复
MonoLogueChi
2019-04-28 23:52:45 +08:00
把 false 当作 null 来处理?只是我猜的
erichuang1994
2019-04-28 23:55:42 +08:00
AngryMagikarp
2019-04-28 23:57:53 +08:00
你们这个接口数据不规范。current 怎么可以同时是两种数据类型,在这里既有可能是 Object,也可能是 boolean。这是不规范的做法。

如果是 Object,那么它的空值就是 null,不是 false。

如果确实需要一个 boolean 字段,应该和 current 分开,再加一个字段。
AngryMagikarp
2019-04-28 23:59:35 +08:00
这种格式不仅是 GSON,大部分语言的 JSON 解析库都会错。
maninfog
2019-04-29 00:02:08 +08:00
我猜你们的后台是 php ?
Nitroethane
2019-04-29 00:10:28 +08:00
@AngryMagikarp 接口数据是不规范...
@maninfog 我是给一个 Web 应用做一个 Android 客户端,算是个人项目,不是公司项目。后台不知道用啥写的......
@MonoLogueChi 刚开始的想法是打算当作 null 处理,但不知道咋操作...
AngryMagikarp
2019-04-29 00:12:34 +08:00
@Nitroethane 给你想个投机取巧的方法,解析之前把所有

"current": false 替换成 "current": null
MonoLogueChi
2019-04-29 00:26:09 +08:00
@Nitroethane Java 我不太懂,反正我知道某些库在解析失败的时候可能会是 null,但是不推荐这样做,如果是 C#的话我知道应该怎么做
helloworld000
2019-04-29 01:05:43 +08:00
为什么不用 protobuf ?
kevinlm
2019-04-29 04:40:40 +08:00
jsonobject 类型判断吧。一般这样的,确实只有 php 能干的出来,简直就是业界毒瘤
alphatoad
2019-04-29 05:04:17 +08:00
Protobuf,请
MoHen9
2019-04-29 08:31:28 +08:00
自定义解析器,你到网上随便搜一下就有

PHP 可能自动隐式转换了
ragnaroks
2019-04-29 08:36:06 +08:00
php 天下第一!

什么,你要我和 php 后端对接?溜了溜了
Jrue0011
2019-04-29 09:15:20 +08:00
GSON 应该可以单独为这个字段自定义一个处理器?
abbenyyy
2019-04-29 09:50:55 +08:00
后端是真毒瘤,特别是这段时间培训班出来的 Java 也喜欢这么干。提个不太优雅的 Android 端处理方案吧,current 用 object 解析,之后要用到 current 的时候再强转。
TommyLemon
2019-04-29 09:56:44 +08:00
类型不稳定是接口大忌,要么你说服后端改,要么自己兼容,
简单的方法是 current 类型定义为兼容两者的 Object,然后
if (current instanceof JsonObject) {
JsonObject cur = (JsonObject) current;
...
}
else if (current instanceof Boolean) {
Boolean cur = (Boolean) current;
...
}
else {
...
}
TommyLemon
2019-04-29 09:58:25 +08:00
不过这种情况我也是见过很多次了,头疼,所以写了一个开源库,彻底解决

点 Star 支持下吧 ^_^
https://www.v2ex.com/t/559388
gaius
2019-04-29 10:00:24 +08:00
全替换成 null 省事
rookiewhy
2019-04-29 10:13:12 +08:00
php 吧,现在的后端就是 php,经常会有这种问题,我都是给坚持 json 数据应该按照规范来。
CononYc
2019-04-29 10:53:18 +08:00
把 current 换成 object 类型把,然后循环的时候再去判断 current 的类型是不是布尔类型,做对应的处理

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/559610

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX