-1

I'm make an API call with retrofit, the problem is the JSON I get from the call. Normally it was a simple Json with an array in it.

[
  {
    "herbID": 1,
    "nameTrival": "Baldrian",
    "nameWissenschaft": "Valeriana officinalis",
  ....
  },
  {
    "herbID": 2,
    "nameTrival": "Ringelblume",
    "nameWissenschaft": "Calendula officinalis",
  ....
  },
  ....
]

The new call looks like this

 [
  [
    {
      "nameTrival": "Baldrian",
      "nameWissenschaft": "Valeriana officinalis",
      "hoeheFrom": 20,
      "hoeheTo": 200,
      "familie": "Baldriangewaechse",
      "pflanzentype": "Staude",
      "auffaelligkeiten": "Je nach Standort sind die Fiederblätter schmäler oder breiter sowie dunkel- oder hellgrün, oft auch unterschiedlich geformt."
    }
  ],
  [
    {
      "standort": "Ufer"
    },
    {
      "standort": "Graben"
    },
    {
      "standort": "Wiesen"
    },
    {
      "standort": "Waldrand"
    }
  ],
  [
    {
      "gebiet": "Nordeuropa"
    },
    {
      "gebiet": "Südeuropa"
    },
    {
      "gebiet": "Westeuropa"
    },
    {
      "gebiet": "Osteuropa"
    },
    {
      "gebiet": "Südosteuropa"
    },
    {
      "gebiet": "Mitteleuropa"
    },
    {
      "gebiet": "Südwesteuropa"
    },
    {
      "gebiet": "Nordosteuoropa"
    },
    {
      "gebiet": "Nordwesteuropa"
    }
  ],
  {
    "fieldCount": 0,
    "affectedRows": 0,
    "insertId": 0,
    "serverStatus": 34,
    "warningCount": 0,
    "message": "",
    "protocol41": true,
    "changedRows": 0
  }
]

I parsed the first Json with the following code

Call<List<Herb>> call = service.getAllHerbs();

            call.enqueue(new Callback<List<Herb>>() {
                @Override
                public void onResponse(Call<List<Herb>> call, Response<List<Herb>> response) {
                    herbList = response.body();
                    loadDataList(herbList);
                }

                @Override
                public void onFailure(Call<List<Herb>> call, Throwable t) {
                    Toast.makeText(PlantListActivity.this, "Unable to load herbs\nCheck your internet connection", Toast.LENGTH_LONG).show();
                }
            });

The new class looks like this

public class Herb{
    ArrayList<Botanical> botanical;
    ArrayList<Location> locations;
    ArrayList<Area> areas;

    public ArrayList<Botanical> getBotanical() {
        return botanical;
    }
    public ArrayList<Location> getLocations() {
        return locations;
    }
    public ArrayList<Area> getAreas() {
        return areas;
    }
}

With the new Json and the class it always fail with the error "java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $"

Didn't I tell gson that the following is an array, after I declare them as an ArrayList? What is wrong with my class?

EDIT: The difference between the possible duplicate and my question is, that the other one has arrays with names. My json arrays doesn't have one, that's why I have a hard time parsing them.

crysis909
  • 25
  • 9

3 Answers3

0

The problem is you're telling Gson you have an object of your type. You don't. You have an array of objects of your type. You can't just try and cast the result like that and expect it to magically work ;)

The User guide for Gson Explains how to deal with this

ismail alaoui
  • 5,748
  • 2
  • 21
  • 38
0

Your new response is very bad. It's impossible to parse that kind of JSON.

It represents array of different objects (different type). So, GSON can do nothing, you have to create a class that is equivalent to the entire response.

Your first JSON response is fine.

Said
  • 689
  • 6
  • 20
0

If you want to handle response with type Herb class, then you need to modify service response like

Rather than [{},{},{}] // this is much difficult to handle

Try this which has to be done at server end

{
                "botanical":[],
                "area" : [],
                "location" : []
 }

Then call will be Call<Herb> someMethod();

If change not possible then handle it as JsonArray

Call<JsonArray> someMethod();

By this you can handle existing response and fetching value key and parse as per requirement. But this is not recommended because it's difficult to maintain if future change and require lot of change