How to set generic type for Gson TypeToken?

EDIT After the experiment, I know for a while that the problem is mine. I cannot specify a generic type inside TypeToken( Type type = new TypeToken<CustomResponse<T>>(){}.getType();). When I change Tto POJOA, I can just run my json deserialization application in POJOA, but not in POJOBand POJOC.

How to add a typical type to TypeToken? Or you can 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 question: Why parseNetworkResponsedoesn’t it return when using a parameterized type?

I suspect the error is in return (Response<T>) Response.success(gson.fromJson(json, typeOfT), HttpHeaderParser.parseCacheHeaders(response));, because it might print Log.d("CustomRequest", json);in the previous line. (see My GsonRequest )

My POJO

public class CustomResponse<T> {
  T response;

  public CustomResponse(T response) {
    this.response = response;
  }

  public T getResponse() {
    return response;
  }
}

My custom deserializer

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>();
    }
}

My 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));
        }
    }
}

Actual call

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
    }
  });
}

I can print Log.d("CustomRequest", json);

json .

return (Response<T>) Response.success(gson.fromJson(json, typeOfT), HttpHeaderParser.parseCacheHeaders(response));.

(Response<T>).

gson.fromJson(json, typeOfT)

+4
1

Type. type erasure Java, , 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));
0

Source: https://habr.com/ru/post/1584694/


All Articles