改进,在响应时解析JSON null异常

时间:2016-10-06 09:51:17

标签: android json retrofit

我在我的应用中使用Retrofit。我有JSON响应,看起来像这样:

{
  "data": {
    "list": [
      {
        "id": 58,
        "beacon_id": "58",
        "bridge_id": null,
        "mesh_id": null,
        "name": "eon_3c",
        "location": "abcdlk",
        "mac_address": "3c:cf:82:8a:e7:fe",
        "firmware": "2.1",
        "pcb_revision": "2.0",
        "battery_level": "99",
        "password": "0000",
        "ib": {
          "turn_on": "1",
          "major": "33",
          "minor": "344",
          "tx_power": "7",
          "interval": "400",
          "uuid": "dae19960-18ea-11e5-8ff0-0002a5d5c521",
          "secure_uuid": "0"
        },
        "euid": {
          "turn_on": "0",
          "namespace": null,
          "instance": null,
          "tx_power": null,
          "interval": null
        },
        "eeid": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null
        },
        "eurl": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null,
          "url": null
        },
        "etlm": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null
        },
        "assigned_bridge_id": null
      },
      {
        "id": 56,
        "beacon_id": "56",
        "bridge_id": null,
        "mesh_id": null,
        "name": "Eon_e6",
        "location": "test",
        "mac_address": "e6:f5:8a:94:b8:c7",
        "firmware": "2.1",
        "pcb_revision": "2.0",
        "battery_level": null,
        "password": "0000",
        "ib": {
          "turn_on": "1",
          "major": "2591",
          "minor": "0",
          "tx_power": "10",
          "interval": "2593",
          "uuid": "dae19960-18ea-11e5-8ff0-0002a5d5c521",
          "secure_uuid": "0"
        },
        "euid": {
          "turn_on": "0",
          "namespace": null,
          "instance": null,
          "tx_power": null,
          "interval": null
        },
        "eeid": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null
        },
        "eurl": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null,
          "url": null
        },
        "etlm": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null
        },
        "assigned_bridge_id": null
      },
      {
        "id": 57,
        "beacon_id": "57",
        "bridge_id": "13",
        "mesh_id": "278",
        "name": "Marta B",
        "location": "lk",
        "mac_address": "e1:4b:64:c3:80:e2",
        "firmware": "2.1",
        "pcb_revision": "2.0",
        "battery_level": "97",
        "password": "0000",
        "ib": {
          "turn_on": "1",
          "major": "325",
          "minor": "10",
          "tx_power": "8",
          "interval": "610",
          "uuid": "dae19960-18ea-11e5-8ff0-0002a5d5c521",
          "secure_uuid": "0"
        },
        "euid": {
          "turn_on": "0",
          "namespace": null,
          "instance": null,
          "tx_power": null,
          "interval": null
        },
        "eeid": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null
        },
        "eurl": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null,
          "url": null
        },
        "etlm": {
          "turn_on": "0",
          "tx_power": null,
          "interval": null
        },
        "assigned_bridge_id": null
      }
    ]
  },
  "ver": 1,
  "time": 1475671202,
  "status": 1,
  "status_msg": ""
}

这是我的回复课程:

public class BeaconResponse {
    @Expose
    public Data data;
    @Expose
    public int ver;
    @Expose
    public int time;
    @Expose
    public int status;
    @Expose
    public String statusMsg;
}

Data课程中,我有ListList个对象。我知道这很糟糕,抱歉。

public class Data extends Model {
    @Column
    public java.util.List<List> list;
}

这是我的List.class

public class List {

    public Integer id;
    public String beaconId;
    public String bridgeId;
    public String meshId;
    public String name;
    public String location;
    public String macAddress;
    public String firmware;
    public String pcbRevision;
    public String batteryLevel;
    public String password;
    public Ib ib;
    public Euid euid;
    public Eeid eeid;
    public Eurl eurl;
    public Etlm etlm;
    public int assignedBridgeId;
}

我认为它应该有用,但事实并非如此。当我尝试将其映射到模型类时,我得到3个对象ResponseList.size = 3,但所有字段都是nulldatastatusMSG等等。你能告诉我为什么会这样吗?在此先感谢您的帮助:)。

我的界面:

@GET("/api/mobile/{language}/{apiVersion}/beacons/list")
void beaconsList(Callback<BasicResponse<BeaconsListResponse>> callback);

public class BeaconsListResponse {
    @Expose
    public List<BeaconResponse> list;
}

这是我的改装电话:

@Subscribe
public void getUserBeacons(GetBeaconsListCommand command) {
    Callback<BasicResponse<BeaconsListResponse>> callback = new Callback<BasicResponse<BeaconsListResponse>>() {
        @Override
        public void success(BasicResponse<BeaconsListResponse> basicResponse, Response response) {
            if (ResponseStatus.SUCCESS.statusCode == basicResponse.status)
                EventBus.post(new BeaconsListFetchedEvent(basicResponse.data));
            else
                EventBus.post(new NetworkFailureEvent(ResponseStatus.getByStatus(basicResponse.status), basicResponse.status_msg));
        }

        @Override
        public void failure(RetrofitError error) {
        }
    };
    service.beaconsList(callback);
}

主要回复类:

public class BasicResponse<T> {
    @Expose
    public T list;
    @Expose
    public int ver;
    @Expose
    public long time;
    @Expose
    public byte status;
    @Expose
    public String status_msg;
}

2 个答案:

答案 0 :(得分:1)

也许您应该像这样创建响应类:

@SerializedName("list")
@Expose
private List<Data> list = new ArrayList<Data>();

尝试通过此工具创建Response类:

http://www.jsonschema2pojo.org/

答案 1 :(得分:1)

问题是您的Java类不能模仿您的JSON模式。 Java类需要完全匹配JSON模式 ,否则GSON将无法反序列化数据。这应该更好地代表您的架构:

public class StandardResponse<T> {

    @SerializedName("data") public T data;
    @SerializedName("ver") public Integer version;
    @SerializedName("time") public Long time;
    @SerializedName("status") public Integer status;
    @SerializedName("status_msg") public String statusMessage;

}

然后,您可以实现包含ListData的<{1}}类:

List

然后转到public class ListData<T> { @SerializedName("list") public List<T> list; } 班级:

Beacon

我会跳过您的public class Beacon { @SerializedName("id") public Integer id; @SerializedName("beacon_id") public String beaconID; @SerializedName("bridge_id") public String bridgeID; @SerializedName("mesh_id") public String meshID; @SerializedName("name") public String name; @SerializedName("location") public String location; @SerializedName("mac_address") public String macAddress; @SerializedName("firmware") public String firmware; @SerializedName("pcb_revision") public String pcbRevision; @SerializedName("battery_level") public String batteryLevel; @SerializedName("password") public String password; @SerializedName("ib") public Ib ib; @SerializedName("euid") public Euid euid; @SerializedName("eeid") public Eeid eeid; @SerializedName("eurl") public Eurl eurl; @SerializedName("etlm") public Etlm etlm; @SerializedName("assigned_bridge_id") public String assignedBridgeID; } IbEuidEdidEurl类,因为它们不应该太难实现上面的课程。

使用这些类,您的Retrofit Etlm应如下所示:

Callback

最后,您可以从回调中获取@GET("/api/mobile/{language}/{apiVersion}/beacons/list") void getBeacons(Callback<StandardResponse<ListData<Beacon>> callback); 对象的列表,如下所示:

Beacon

根据您的示例JSON,上面的代码应该在logcat中打印以下内容:

service.getBeacons(new Callback<StandardResponse<ListData<Beacon>>> {

    @Override
    public void success(StandardResponse<ListData<Beacon>> standard, Response response) {
        Log.d(TAG, "Status: " + standard.status + "; with message: " + standard.statusMessage);
        List<Beacon> beacons = standard.data.list;

        for(Beacon beacon: beacons) {
            Log.d(TAG, "Beacon ID: " + beacon.id);
        }
    }

    @Override
    public void failure(RetrofitError error) {
        // TODO: implement error handling
    }

});

<强>更新

以下是Status: 1, with message: Beacon ID: 58 Beacon ID: 56 Beacon ID: 57 IbEuidEdidEurl类:

Etlm