如何将泛型类型为GSON的TypeToken? [英] How do I put generic type for Gson's TypeToken?
问题描述
修改经历过了一段时间后,我知道我的问题是。我不能把泛型类型在 TypeToken
(类型类型=新TypeToken< CustomResponse< T>>(){}的getType()。
)。当我更改 T
到 POJOA
,我可以运行我的应用程序就好了反序列化JSON到 POJOA
,但不进 POJOB
和 POJOC
。
EDIT After experimenting for a while, I know my problem is. I can't put generic type inside TypeToken
(Type type = new TypeToken<CustomResponse<T>>(){}.getType();
). When I change T
into POJOA
, I can run my app just fine to deserialize json into POJOA
, but not into POJOB
and POJOC
.
我如何把泛型类型为TypeToken?或者说,是否有可能做这样的事情:
How do I put generic type into TypeToken? Or, is it possible to do something like this:
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();
};
previous问题:?使用参数化类型时,为什么 parseNetworkResponse
返回任何
Previous Question: Why do parseNetworkResponse
return nothing when using parametrized type?
我怀疑的错误是在收益率(响应&LT; T&GT;)Response.success(gson.fromJson(JSON,typeOfT),HttpHeaderParser.parseCacheHeaders(响应));
的一部分,因为它可以打印 Log.d(CustomRequest,JSON);
上previous线。 (请查看我GsonRequest )
I suspect the error is in return (Response<T>) Response.success(gson.fromJson(json, typeOfT), HttpHeaderParser.parseCacheHeaders(response));
part, because it could print Log.d("CustomRequest", json);
on previous line. (please look at My 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响应就好了。
so that means I get the json response just fine.
问题是收益率(响应&LT; T&GT;)Response.success(gson.fromJson(JSON,typeOfT),HttpHeaderParser.parseCacheHeaders(响应));
。
时转换为时出错(响应&LT; T&GT;)
。
或者是它 gson.fromJson错误(JSON,typeOfT)
推荐答案
您必须指定键入
明确。有一个在Java中,类型擦除这基本上意味着,在运行时都 T
实例都替换为对象
。
You have to specify the Type
explicitly. There's type erasure in Java, which basically means that at runtime all instances of T
are replaced with Object
.
您应该要么写不同的响应类型的三种不同的解串器( POJOA
, POJOB
, POJOC
),或者写一个通用的。像这样的东西应该工作:
You should either write three different deserializers for different response types(POJOA
, POJOB
, POJOC
) or write a generic one. Something like this should work:
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));
这篇关于如何将泛型类型为GSON的TypeToken?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!