Reputation: 7577
I am implementing an API from Rejseplanen.dk where I can receive either a list of someting or an object. The problem is that I don't know when I will be receiving what. Here is a small example of what I can receive:
Example here I will receive a list: (full request:
"JourneyName": [
{
"name": "IC 865",
"routeIdxFrom": "0",
"routeIdxTo": "29"
},
{
"name": "IC 865",
"routeIdxFrom": "29",
"routeIdxTo": "37"
}
],
"JourneyType": [
{
"type": "IC",
"routeIdxFrom": "0",
"routeIdxTo": "29"
},
{
"type": "IC",
"routeIdxFrom": "29",
"routeIdxTo": "37"
}
],
Example with an object:
"JourneyName": {
"name": "Bybus 5",
"routeIdxFrom": "0",
"routeIdxTo": "41"
},
"JourneyType": {
"type": "TB",
"routeIdxFrom": "0",
"routeIdxTo": "41"
},
I am using GSON to parse the received JSON string into a JAVA Object like this:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
MyClass myClass = gson.fromJson(getResponse(), MyClass.class);
How will I be able to make this convertion? I thought that I could simply treat the object as a list but if I do I will get this exception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 258 column 18 path $.JourneyDetail.JourneyName
Upvotes: 0
Views: 113
Reputation: 15533
Write a custom TypeAdapter:
public class Journey {
private JourneyName[] journeyNameArr;
private JourneyType[] journeyTypeArr;
}
public class JourneyName {
private String name, routeIdxFrom, routeIdxTo;
}
public class JourneyType {
private String type, routeIdxFrom, routeIdxTo;
}
public class JourneyTypeAdapter extends TypeAdapter<Journey> {
@Override
public Journey read(JsonReader in) throws IOException {
Journey journey= new Journey();
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
JsonObject jo = (JsonObject)jsonParser.parse(in);
JsonElement jeJourneyName = jo.get("JourneyName");
if(jeJourneyName instanceof JsonArray) {
journey.journeyNameArr = gson.fromJson(jeJourneyName, JourneyName[].class);
} else if(jeJourneyName instanceof JsonObject) {
journey.journeyNameArr = new JourneyName[1];
journey.journeyNameArr[0] = gson.fromJson(jeJourneyName, JourneyName.class);
}
JsonElement jeJourneyType = jo.get("JourneyType");
if(jeJourneyType instanceof JsonArray) {
journey.journeyTypeArr = gson.fromJson(jeJourneyType, JourneyType[].class);
} else if(jeJourneyType instanceof JsonObject) {
journey.journeyTypeArr = new JourneyType[1];
journey.journeyTypeArr[0] = gson.fromJson(jeJourneyType, JourneyType.class);
}
return journey;
}
@Override
public void write(JsonWriter out, Journey item) throws IOException {
throw new IllegalArgumentException("JourneyTypeAdapter.write method not implemented!");
}
}
Test:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Journey.class, new JourneyTypeAdapter());
Gson gson = gsonBuilder.create();
String jsonTest1 = "{\"JourneyName\":[{\"name\":\"IC 865\",\"routeIdxFrom\":\"0\",\"routeIdxTo\":\"29\"},{\"name\":\"IC 865\",\"routeIdxFrom\":\"29\",\"routeIdxTo\":\"37\"}],\"JourneyType\":[{\"type\":\"IC\",\"routeIdxFrom\":\"0\",\"routeIdxTo\":\"29\"},{\"type\":\"IC\",\"routeIdxFrom\":\"29\",\"routeIdxTo\":\"37\"}]}";
String jsonTest2 = "{\"JourneyName\":{\"name\":\"Bybus 5\",\"routeIdxFrom\":\"0\",\"routeIdxTo\":\"41\"},\"JourneyType\":{\"type\":\"TB\",\"routeIdxFrom\":\"0\",\"routeIdxTo\":\"41\"}}";
Journey journey0 = gson.fromJson(jsonTest1, Journey.class);
Journey journey1 = gson.fromJson(jsonTest2, Journey.class);
Upvotes: 1