编辑经过一段时间的实验,我知道我的问题是。我不能将通用类型放在TypeToken
(Type type = new TypeToken<CustomResponse<T>>(){}.getType();
)中。当我将T
更改为POJOA
时,我可以正常运行我的应用,将json反序列化为POJOA
,但不能反映为POJOB
和POJOC
。
如何将泛型类型放入TypeToken?或者,是否可以这样做:
if (T == POJOA) {
Type type = new TypeToken<CustomResponse<POJOA>>(){}.getType();
} else if (T == POJOB) {
Type type = new TypeToken<CustomResponse<POJOB>>(){}.getType();
} else if (T == POJOC) {
Type type = new TypeToken<CustomResponse<POJOC>>(){}.getType();
};
上一个问题:为什么使用参数化类型时parseNetworkResponse
什么都不返回?
我怀疑错误发生在return (Response<T>) Response.success(gson.fromJson(json, typeOfT), HttpHeaderParser.parseCacheHeaders(response));
部分,因为它可能会在前一行打印Log.d("CustomRequest", json);
。 (请查看我的GsonRequest )
我的POJO
public class CustomResponse<T> {
T response;
public CustomResponse(T response) {
this.response = response;
}
public T getResponse() {
return response;
}
}
我的自定义反序列化程序
public class POJOADeserializer implements JsonDeserializer<CustomResponse<POJOA>> {
@Override
public CustomResponse<POJOA> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
//some deserializing thing
return new CustomResponse<POJOA>();
}
}
public class POJOBDeserializer implements JsonDeserializer<CustomResponse<POJOB>> {
@Override
public CustomResponse<POJOB> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
//some deserializing thing
return new CustomResponse<POJOB>();
}
}
public class POJOCDeserializer implements JsonDeserializer<CustomResponse<POJOC>> {
@Override
public CustomResponse<POJOC> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
//some deserializing thing
return new CustomResponse<POJOC>();
}
}
我的GsonRequest
public class CustomRequest<T> extends JsonRequest<T> {
private final Gson gson;
private final Type typeOfT
private final Response.Listener<T> listener;
public CustomRequest(int method,
String url,
Type typeOfT,
JSONObject params,
Response.Listener<T> listener,
Response.ErrorListener errorListener) {
super(method, url, params.toString(), listener, errorListener);
this.typeOfT = typeOfT;
this.listener = listener;
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(new TypeToken<CustomResponse<POJOA>>(){}.getType(), new POJOADeserializer());
gsonBuilder.registerTypeAdapter(new TypeToken<CustomResponse<POJOB>>(){}.getType(), new POJOBDeserializer());
gsonBuilder.registerTypeAdapter(new TypeToken<CustomResponse<POJOC>>(){}.getType(), new POJOCDeserializer());
this.gson = gsonBuilder.create();
}
@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));
Log.d("CustomRequest", json);
return (Response<T>) Response.success(gson.fromJson(json, typeOfT), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
实际调用
public <T> void get(String url,
Response.Listener<CustomResponse<T>> listener,
Response.ErrorListener errorListener) {
Type type = new TypeToken<CustomResponse<T>>(){}.getType();
CustomRequest<CustomResponse<T>> request = new CustomRequest<>(Request.Method.GET, url, type, null, listener, errorListener);
Volley.newRequestQueue(context.getApplicationContext()).add(request);
}
public void getResponse() {
String url = //some url;
get(url, new Response.Listener<CustomResponse<POJOA>>() {
@Override
public void onResponse(CustomResponse<POJOA> response) {
//do something
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//do something
}
});
}
我可以打印Log.d("CustomRequest", json);
这意味着我得到了json响应就好了。
问题是return (Response<T>) Response.success(gson.fromJson(json, typeOfT), HttpHeaderParser.parseCacheHeaders(response));
。
投射到(Response<T>)
时是否有错误。
或gson.fromJson(json, typeOfT)
答案 0 :(得分:0)
您必须明确指定Type
。 Java中有type erasure,这基本上意味着在运行时T
的所有实例都被Object
替换。
您应该为不同的响应类型(POJOA
,POJOB
,POJOC
)编写三个不同的反序列化器,或者编写一个通用的反序列化器。这样的事情应该有效:
public class GenericConverter implements JsonDeserializer<CustomResponse<?>> {
private Type typeOfResponse;
public GenericConverter(Type typeOfResponse) {
this.typeOfResponse = typeOfResponse;
}
public CustomResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) {
CustomResponse response = new CustomResponse();
response.setResponse(ctx.deserialize(json.getAsJsonObject().get("response"), typeOfResponse));
return response;
}
}
并适当注册:
gsonBuilder.registerTypeAdapter(new TypeToken<CustomResponse<POJOA>>(){}.getType(),
new GenericConverter(POJOA.class));
gsonBuilder.registerTypeAdapter(new TypeToken<CustomResponse<POJOB>>(){}.getType(),
new GenericConverter(POJOB.class));
gsonBuilder.registerTypeAdapter(new TypeToken<CustomResponse<POJOC>>(){}.getType(),
new GenericConverter(POJOC.class));