i just had a problem converting the JSON from Phillips Hue Lights (Response) to a Model. Since it may contain several "unknown" keys in success and/or may contain just a String for success i had to write/use a TypeAdapter and a deserializer aswell. This works but im pretty sure there is a better way to solve this.
Dummy JSONS:
[{"success":{"/config/name":"My bridge"}}]
and
[{
"success":{"id": "3"}
}]
and
[
{"success":{ "address": "/groups/1/action/on", "value": true}},
{"success":{ "address": "/groups/1/action/effect", "value":"colorloop"}},
{"success":{ "address": "/groups/1/action/hue", "value":6000}}
]
And the JSON with just a String
[{
"success": "/config/whitelist/1234567890 deleted."
}]
It may also contain "error" but this isnt the problem. Since the object in address is unknown i use a Adapter from https://stackoverflow.com/questions/17627869/simple-way-to-strip-outer-array-of-responses-in-gson which works fine as long as its an Object. Since it may also contain a String i had to create a JsonDeserializer which validates if its a JSONObject and if not, it sets another variable in the Model with the message. It works, but i always have to revalidate if the message or success it set.
This is my JSONDeserializer
public class HueResponseDeserializer implements JsonDeserializer<HueResponse> {
private final String TAG = HueResponseDeserializer.class.getSimpleName();
@Override
public HueResponse deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
HueResponse response = new HueResponse();
JsonObject jsonObject = jsonElement.getAsJsonObject();
if (jsonObject.get("success").isJsonObject()) {
for (Map.Entry<String, JsonElement> entry : jsonObject.getAsJsonObject("success").entrySet()) {
response.setSuccess(new HashMap<String, Object>() {{
put(entry.getKey(), entry.getValue());
}});
}
} else {
response.setSuccessMessage(jsonObject.get("success").getAsString());
}
if (jsonObject.has("error") && jsonObject.get("error").isJsonObject()) {
for (Map.Entry<String, JsonElement> entry : jsonObject.getAsJsonObject("error").entrySet()) {
response.setError(context.deserialize(entry.getValue(), HueResponse.Error.class));
}
}
return response;
}
}
And my Model
public class HueResponse {
private Map<String, Object> success;
private Error error;
private String successMessage;
public String getSuccessMessage() {
return successMessage;
}
public void setSuccessMessage(String successMessage) {
this.successMessage = successMessage;
}
public Map<String, Object> getSuccess() {
return success;
}
public Error getError() {
return error;
}
public void setSuccess(Map<String, Object> success) {
this.success = success;
}
public void setError(Error error) {
this.error = error;
}
public static class Error {
private int type;
private String address;
private String description;
public int getType() {
return type;
}
public String getAddress() {
return address;
}
public String getDescription() {
return description;
}
@Override
public String toString() {
return "Type: " + this.type
+ " Address: " + this.address
+ " Description: " + this.description;
}
}
}