简体   繁体   中英

Android GSON - using templates for JSON structured objects

My server responds with JSON object always containing the same structre:

[int id, Error error, T result] where result is a type depending on the JSON method being called. I'm trying to use GSON for deserialization but it looks like having problems when I use generics.

private <T> T executeRequest(String methodName, Object[] params,
        Class<T> resultType) throws HttpException, IOException {
    final Gson gson = buildGson();
    final URL url = new URL(WEB_URL + methodName);


    final ZenfolioRequest request = new ZenfolioRequest();
    request.setMethod(methodName);
    request.setId(getNextRequestId());
    request.setParams(params);

    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod(POST);
    connection.setRequestProperty(USER_AGENT_PROPERTY, AGENT_NAME);
    connection.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
    connection.setRequestProperty(ACCEPT, APPLICATION_JSON);
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setChunkedStreamingMode(0);
    connection.connect();

    final String toSend = gson.toJson(request);
    connection.getOutputStream().write(toSend.getBytes());
    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {

        final InputStream in = new BufferedInputStream(
                connection.getInputStream());

        //String response = readResponseString(in);

        final T result = gson.fromJson(new InputStreamReader(in, UTF_8),
                resultType);
        return result;
    } else {
        throw new HttpException();
    }

}

Example method:

@Override
public ZenfolioResponse<AuthChallenge> getChallenge(String loginName) {

    try {
        final String methodName = "GetChallenge";
        return executeRequest(methodName, new Object[] { loginName },
                new ZenfolioResponse<AuthChallenge>().getClass());
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
    }
    return null;
}


public class ZenfolioResponse<T>{

@SerializedName("id")
int id;
@SerializedName("error")
Error error;
@SerializedName("result")
T result;

public T getResult() {
    return result;
}
public void setResult(T result) {
    this.result = result;
}
public Error getError() {
    return error;
}
public void setError(Error error) {
    this.error = error;
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}

}

The problem is the object ZenfolioResponse is incorrectly filled with the Result body. It is not typed, it is an Object instance instead of AuthChallenge type.

Does anybody have any hints on how to tweak this?

Try to use TypeToken from GSON library. It will help you to parse generic type. I found example here: http://www.studytrails.com/java/json/java-google-json-serializing-classes-with-generic-type.jsp

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM