2016-10-06 7 views
0

Ich benutze Retrofit in meiner App. Ich habe JSON-Antwort bekam, die wie folgt aussieht:Retrofit, Parsing JSON null Ausnahme bei Antwort

{ 
    "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": "" 
} 

Hier ist meine Antwort Klasse:

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

In der Data Klasse I List mit List Objekte haben. Ich weiß, es ist eine schlechte Namensgebung, tut mir leid.

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

Und hier ist mein 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; 
} 

Ich denke, es sollte funktionieren, aber es funktioniert nicht. Wenn ich versuche, es der Modellklasse zuzuordnen, bekomme ich 3 Objekte ResponseList.size = 3, aber alle Felder sind null: data, statusMSG und so weiter. Kannst du mir sagen, warum das so ist? Vielen Dank im Voraus für :) helfen

Meine Schnittstelle:

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

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

Hier ist mein Retrofit Aufruf:

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

Haupt Response-Klasse:

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

Können Sie Ihre Retrofit Anruf veröffentlichen – Raghunandan

+0

ich die Post – Bartos

+0

Was bearbeitet haben ist Grundantwort für? –

Antwort

1

Vielleicht sollten Sie erstellen Ihre Antwort Klasse wie diese:

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

Versuchen Sie Ihre Response-Klasse über dieses Tool zu erstellen:

http://www.jsonschema2pojo.org/

1

Das Problem ist, dass Ihre Java-Klassen imitieren nicht Ihre JSON-Schema. Ihre Java-Klassen müssen dem JSON-Schema genau entsprechen oder GSON kann die Daten nicht deserialisieren. Dies sollte besser Ihr Schema darstellen:

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; 

} 

Dann können Sie eine ListData Klasse implementieren, die eine List enthält:

public class ListData<T> { 

    @SerializedName("list") public List<T> list; 

} 

Dann auf Ihre Beacon Klasse:

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; 

} 

Ich werde überspringen Ihre Ib, Euid, Edid, Eurl und Etlm Klassen, da sie basierend auf den oben genannten Klassen nicht zu schwierig zu implementieren sein sollten.


Mit diesen Klassen Ihr Retrofit Callback sollte wie folgt aussehen:

@GET("/api/mobile/{language}/{apiVersion}/beacons/list") 
void getBeacons(Callback<StandardResponse<ListData<Beacon>> callback); 

Und schließlich können Sie Ihre Liste der Beacon Objekte aus dem Rückruf erhalten wie folgt:

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 
    } 

}); 

Basierend auf Ihrem Beispiel-JSON sollte der obige Code Folgendes in logcat drucken:

Status: 1, with message: 
Beacon ID: 58 
Beacon ID: 56 
Beacon ID: 57 

aktualisieren

Hier sind die Ib, Euid, Edid, Eurl und Etlm Klassen:

public class Ib { 

    @SerializedName("turn_on") public String turnOn; 
    @SerializedName("major") public String major; 
    @SerializedName("minor") public String minor; 
    @SerializedName("tx_power") public String txPower; 
    @SerializedName("interval") public String interval; 
    @SerializedName("uuid") public String uuid; 
    @SerializedName("secure_uuid") public String uuidSecure; 

} 

public class Euid { 

    @SerializedName("turn_on") public String turnOn; 
    @SerializedName("namespace") public String nameSpace; 
    @SerializedName("instance") public String instance; 
    @SerializedName("tx_power") public String txPower; 
    @SerializedName("interval") public String interval; 

} 

public class Edid { 

    @SerializedName("turn_on") public String turnOn; 
    @SerializedName("tx_power") public String txPower; 
    @SerializedName("interval") public String interval; 

} 

public class Eurl { 

    @SerializedName("turn_on") public String turnOn; 
    @SerializedName("tx_power") public String txPower; 
    @SerializedName("interval") public String interval; 
    @SerializedName("url") public String url; 

} 

public class Etlm { 

    @SerializedName("turn_on") public String turnOn; 
    @SerializedName("tx_power") public String txPower; 
    @SerializedName("interval") public String interval; 

} 
+0

Funktioniert immer noch nicht:/Alles ist geparst ok, aber Ib, Euid, Edid, Eurl und Etlm sind null:/ – Bartos

+0

@Bartos Aber alles andere geparst wie erwartet? Vielleicht haben Sie diese Klassen nicht korrekt erstellt? Ich werde mit einer Darstellung dieser Klassen aktualisieren. – Bryan

+0

Alles ist geparst ok außer Objekte:/Ich habe Klassen erstellt, wie Sie gesagt haben. Wenn ich die App debugge, habe ich diese Ausnahme beim Erstellen der EonBeaconModel-Methode, die die Ausnahme 'java.lang.NullPointerException' ausgelöst hat. Kann nicht evaluieren pl.netizens.eonbeacon.storage.EonBeaconModel.toString() – Bartos