Reputation: 2049
Json that is returned by server has an element that is sometimes an empty array and other times an object. I wrote custom TypeAdapterFactory to best of my knowledge:
@Override
public T read(final JsonReader in) throws IOException {
if (in.peek() == JsonToken.BEGIN_ARRAY) {
return null;
} else {
return delegateTypeAdapter.read(in);
}
}
But it still throws: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 652 path $.timetable
This is my Timetable class:
public final class Timetable implements Serializable{
private final Map<Integer, String> teachers;
private final Map<Integer, String> hours;
private final Map<Integer, String> rooms;
private final Map<Integer, String> groups;
private final Map<Integer, String> subjects;
private final Map<Integer, List<Map<String, String>>> entries;
}
So sometimes when timetable is empty json looks like this: "timetable": []
When it is not empty it is like this:
"timetable": {
"teachers": {
"762": "sfsdfsdf",
},
"hours": {
"1": "09:00",
},
"rooms": {
"439": "sdfsdfsdf",
},
"subjects": {
"738": "sdfsdfdsf",
},
"entries": {
"10": [
{
"week": "1",
"day": "6",
"date": "2017-03-01",
"hour": "1",
"type": "0",
"course": "3844",
"teacher": "59502",
"room": "640",
"p": "-1",
"table": "1447"
},
{
"week": "1",
"day": "6",
"date": "2017-03-01",
"hour": "2",
"type": "0",
"course": "4047",
"teacher": "50792",
"room": "799",
"p": "-1",
"table": "1447"
}
]
}
Upvotes: 1
Views: 258
Reputation: 1354
I had a problem similar to yours (I was getting an empty string when the array had no elements) so i created a generic GsonArrayDeserializer, this modified version for an Ojbect sould work for you
public class GsonObjectDeserializer<T> implements JsonDeserializer<T> {
@Override
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Gson gson = new Gson();
T result = null;
if (json.isJsonObject()) {
result = gson.fromJson(json.getAsJsonObject(), typeOfT);
}
}
}
And using it like this
Gson gson = new GsonBuilder()
.registerTypeAdapter(Timetable.class , new GsonObjectDeserializer<Timetable>(Timetable.class))
.create();
EXTRA:
To use it with Retrofit2 add it like this
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.URL_BASE)
...... //other paramaeters
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
It's well explained here
Upvotes: 2