I am using Volley
and Gson
with Java Reflection
to deserialize my JSON
response. I have specific JSON
field that can be returned as JSONObject
which means an object class or JSONArray
which means an array/list of object class.
I need to reflect this field and change its type at runtime.
Here is my Object class:
public class BaseResponse implements Parsable, Serializable {
@SerializedName("status message")
@Expose
private String statusMessage;
@SerializedName("status code")
@Expose
private Integer statusCode;
@SerializedName("data")
@Expose
private Object object = null;
public String getStatusMessage() {
return statusMessage;
}
public void setStatusMessage(String statusMessage) {
this.statusMessage = statusMessage;
}
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
@Override
public Object parse(JsonElement jsonElement) {
return new Gson().fromJson(jsonElement, BaseResponse.class);
}
}
The "data"
field might be a JSONObject
(need to parse it as SomeObjectClass
) or JSONArray
(need to parse it as list of SomeObjectClass2
)
When I get response and return as Gson
format, I got a LinkedTreeMap
which I can't parse it as SomeObjectClass
or SomeObjectClass2
I need to reflect the "data"
field to get any kind of Object classes based on the response.
I return the response using the following class:
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Response.Listener<T> listener;
private final Type type;
/**
* Make a GET request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson's reflection
* @param headers Map of request headers
*/
public GsonRequest(int method, String url, Class<T> clazz, Type type, Map<String, String> headers,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.clazz = clazz;
this.type = type;
this.headers = headers;
this.listener = listener;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
How to achieve my goal?
Aucun commentaire:
Enregistrer un commentaire