0

This error is back !

I'm a beginner with Retrofit, I've saw this post: Retrofit: Expected BEGIN_OBJECT but was BEGIN_ARRAY

But I still can't make it work even if I try to adapt it to my model. So my error is:

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 55 path $[0].genericDevice

What I get:

[
  {
    "deviceUuid": "btB4:99:4C:59:F8:1F",
    "genericDevice": {
      "manufacturerName": "BeeWi",
      "productName": "BeeWi BBL207",
      "smartFunctions": [
        "switch",
        "rgbled",
        "whiteled"
      ]
    }
  },
  {
    "deviceUuid": "btD0:39:72:B8:93:F2",
    "genericDevice": {
      "manufacturerName": "AwoX",
      "productName": "SML-c9",
      "smartFunctions": [
        "switch",
        "whiteled",
        "rgbled"
      ]
    }
  },
  {
    "deviceUuid": "bt20:C3:8F:E4:B2:2A",
    "genericDevice": {
      "manufacturerName": "Iwedia",
      "productName": "RTRKSP",
      "smartFunctions": [
        "switch",
        "smartmeter"
      ]
    }
  },
  {
    "deviceUuid": "btA0:14:3D:0C:D3:74",
    "genericDevice": {
      "manufacturerName": "Parrot",
      "productName": "Flower power",
      "smartFunctions": [
        "switch",
        "battery",
        "plantmanager"
      ]
    }
  },
  {
    "deviceUuid": "bt78:A5:04:5A:0B:36",
    "genericDevice": {
      "manufacturerName": "BeeWi",
      "productName": "BeeWi SmartClim",
      "smartFunctions": [
        "temperaturehumidity"
      ]
    }
  },
  {
    "deviceUuid": "bt54:4A:16:59:E4:86",
    "genericDevice": {
      "manufacturerName": "AwoX",
      "productName": "AL-Bc7",
      "smartFunctions": [
        "switch",
        "rgbled",
        "whiteled",
        "oildiffuser"
      ]
    }
  }
]

The parsing class' attributes:

private String             deviceUuid;
private IoTGenericDevice   ioTGncDvc;

The IoTGenericDevice subclass' attributes:

public String                   manufacturerName;
public String                   productName;
public ArrayList<String>        smartFunctions = new ArrayList<String>();

The Retrofit call:

@GET("/iot/scanning")
public void             getIoTs(@Header(Auth.ID_SESSION_HEADER) String idSession, Callback<IoT[]> cbk);

The Manager:

public void             getIoTs(final CallbackIoTs cbkIoTs)
    {
        AdapterUtils.createBboxService(bbox, IBboxIoTService.class).getIoTs
                (bbox.getSessionId(), new Callback<List<IoT>>()                                       //REST call
                {
                    @Override
                    public void success(List<IoT> iots, Response rsp)
                    {
                        int statCode = rsp.getStatus();

                        if (statCode == 200) {
                            List<IoT> iotLst = Arrays.asList(iots);
                            Log.e(LOG_TAG, iotLst.get(0).getIoTGncDvc().getMnf());
                            cbkIoTs.onResult(statCode, iotLst);
                        } else {
                            Log.e(LOG_TAG, "Unexpected response while getting IoTs. HTTP code: "
                                    + String.valueOf(statCode)
                                    + " - 200 expected");
                            cbkIoTs.onResult(statCode, null);
                        }
                    }

                    @Override
                    public void failure(RetrofitError rtfErr)
                    {
                        int statCode = 500;

                        if (rtfErr.getResponse() != null)
                            statCode = rtfErr.getResponse().getStatus();
                        Log.e(LOG_TAG, "Error while getting IoTs. HTTP code: "
                                + String.valueOf(statCode)
                                + " - Server response: "
                                + rtfErr.getMessage());
                        cbkIoTs.onResult(statCode, null);
                    }
                });
    }
Community
  • 1
  • 1
X.LINK
  • 133
  • 7
  • I'm not sure, but I think that is a problem with the data sent from the server. It's not in JSON format I guess. I used to have this problem, since sometimes server responds differently – capt.swag Sep 01 '15 at 09:21
  • 3
    your error is the other way around, expected array but found object!, although your json is valid as JsonArray, so it might be a typo?anyways try this `Callback`, – Yazan Sep 01 '15 at 09:27

1 Answers1

1

This should be the object:

public class Test{

@Expose
private String deviceUuid;
@Expose
private GenericDevice genericDevice;
}

And this is Generic Device object:

public class GenericDevice {

@Expose
private String manufacturerName;
@Expose
private String productName;
@Expose
private List<String> smartFunctions = new ArrayList<String>();
}

Retrofit call:

@GET("/iot/scanning")
public void             getIoTs(@Header(Auth.ID_SESSION_HEADER) String idSession, Callback<List<Test>> cbk);

Adapter call:

AdapterUtils.createBboxService(bbox, IBboxIoTService.class).getIoTs
                (bbox.getSessionId(), new Callback<List<Test>>(){...}
Mikelis Kaneps
  • 4,576
  • 2
  • 34
  • 48
  • I made the changes you've suggested. but got the same error, maybe I made something wrong. I put the related code in "The Manager" section of my first post. – X.LINK Sep 02 '15 at 08:47
  • Things have changed a little (parsing class attributes, Retrofit call and Manager updated + IoTGenericDevice subclass added), but when I'm fetching my IoT lists in my manager and LOG_TAG it, the subclasses GenericDevice seems null. Did I missed something ? – X.LINK Sep 07 '15 at 12:04
  • 1
    @X.LINK check if the name in the class is the same as in json, and check if you have added "@Expose." – Mikelis Kaneps Sep 07 '15 at 12:09
  • The @Expose isn't needed, but matching names was the real problem. Problem solved ! – X.LINK Sep 07 '15 at 13:02
  • 1
    yes, "@Expose" is not needed if you don't make it needed creating Gson, but if you ever need a field inside the class that you don't need to parse, "@Expose" and special Gson could come in handy. That's good that your problem is solved. – Mikelis Kaneps Sep 07 '15 at 13:07
  • I'll remember that :D By the way, where did you learned about the matching names ? I only found one blog about it and as far as I remember I didn't find that in Retrofit's documentation :/ – X.LINK Sep 07 '15 at 13:15
  • 1
    I am not sure where. But you could use this, if you want different name for the field- "@SerializedName("items_count") @Expose int itemsCount;" – Mikelis Kaneps Sep 07 '15 at 13:16