使用Reflection将Java gson.fromJson()转换为POJO会导致java.lang.ClassCastException

时间:2016-04-21 04:02:48

标签: java android json gson

我在使用Gson解析一些JSON时遇到了一些噩梦般的问题。

我试图解析的Json结构如下所示:

{ "user_id" : "833", "message" : "User created and registered" }

当我使用以下代码解析Json时:

Type response = gson.fromJson(jsonString, new TypeToken<RestResponse>(){}.getType());

我收到以下错误:

java.lang.ClassCastException:... RestResponse无法强制转换为java.lang.reflect.Type

我正在解析以下POJO:

import java.lang.reflect.Type;

public class RestResponse {

    private void RestResponse() {
        // Constructor required for GSON
    }

    private StatusCode statusCode;
    private String content;
    private Object data;
    private Type output;
    private String user_id;
    private String message;
    private String error;

    public String getUserID() {
        return this.user_id;
    }
    public void setUserID(String user_id) {
        this.user_id = user_id;
    }
    public String getMessage() { return this.message; }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getError() { return this.error; }
    public void setError(String error) { this.error = error; }
    public StatusCode getStatusCode() {
        return statusCode;
    }
    public void setStatusCode(StatusCode statusCode) {
        this.statusCode = statusCode;
    }
    public final String getContent() {
        return content;
    }
    public final void setContent(final String content) {
        this.content = content;
    }
    public final Object getData() {
        return data;
    }
    public final void setData(final Object data) {
        this.data = data;
    }
    public final Type getOutput() {
        return output;
    }
    public final void setOutput(final Type output) {
        this.output = output;
    }
    @Override
    public final String toString() {
        return String.format("%s", this.content);
    }
}

我返回Type而不是RestResponse对象的原因是因为我根据响应Type的类型调用回调。然后我像这样处理代码:

if (statusCode == StatusCode.SUCCESS) {
    if (requestCode == AppConstants.REQUEST_REGISTRATION) {
        if (data instanceof RestResponse) {
            RestResponse restResponse       = (RestResponse) data;
            AppDelegate delegate            = (AppDelegate) getApplicationContext();
            delegate.name                   = nameText.getText().toString();
            delegate.email                  = emailText.getText().toString();
            delegate.mobile                 = validatedFormattedNum;
            delegate.referredID             = "";
            delegate.isRegistered           = 1;
            delegate.uid                    = restResponse.getUserID();
            delegate.setInMemory();
        } else {
            if(data instanceof ApiErrorResponse) {
                ApiErrorResponse apiErrorResponse = (ApiErrorResponse) data;
                ...
                ...
                ...

任何人都希望看到堆栈跟踪:

E/com.sourgun.http.AppParser: General exception encountered in parse()    com.sourgun.http.RestResponse cannot be cast to java.lang.reflect.Type
04-22 12:51:13.748 31779-31779/? W/System.err: java.lang.ClassCastException: com.sourgun.http.RestResponse cannot be cast to java.lang.reflect.Type
04-22 12:51:13.748 31779-31779/? W/System.err:     at com.sourgun.http.AppParser.parse(AppParser.java:37)
04-22 12:51:13.749 31779-31779/? W/System.err:     at com.sourgun.http.RestController.onResponse(RestController.java:85)
04-22 12:51:13.750 31779-31779/? W/System.err:     at com.sourgun.http.AsyncTaskExecutor.onPostExecute(AsyncTaskExecutor.java:66)
04-22 12:51:13.750 31779-31779/? W/System.err:     at com.sourgun.http.AsyncTaskExecutor.onPostExecute(AsyncTaskExecutor.java:14)
04-22 12:51:13.751 31779-31779/? W/System.err:     at android.os.AsyncTask.finish(AsyncTask.java:651)
04-22 12:51:13.751 31779-31779/? W/System.err:     at android.os.AsyncTask.-wrap1(AsyncTask.java)
04-22 12:51:13.752 31779-31779/? W/System.err:     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
04-22 12:51:13.753 31779-31779/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
04-22 12:51:13.753 31779-31779/? W/System.err:     at android.os.Looper.loop(Looper.java:148)
04-22 12:51:13.754 31779-31779/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5422)
04-22 12:51:13.754 31779-31779/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
04-22 12:51:13.755 31779-31779/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
04-22 12:51:13.755 31779-31779/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

3 个答案:

答案 0 :(得分:0)

获取ClassCaseException的原因:

  

那是因为类JsonParsing我们调用的方法“解析”   gson.fromJson(jsonString,new TypeToken(){}。getType())   它将使用Reflection将String转换为java对象。

尝试下面的代码:

RestResponse mRestResponse = gson.fromJson(reader, RestResponse.class)); 

请参阅使用GSON解析JSON的详细信息description

使用这种方法,您可以重用Response类来添加任何其他字段,以获取您可能希望从JSON中提取的其他数据成员

希望它会对你有所帮助。

答案 1 :(得分:-1)

你有一个RestResponse类,

当你这样做时:

response = gson.fromJson(jsonString, new TypeToken<RestResponse>(){}.getType());

是因为你想从json String得到某种类令牌,那就是错误... 你想要/需要一个对象而只有一个类的对象 RestResponse ,所以你需要这样做:

response = gson.fromJson(jsonString, RestResponse.class);

答案 2 :(得分:-1)

问题是RestResponse没有正确定义,它应该被定义为(包括实现Type和正确的公共构造函数):

 public class RestResponse implements Type {

    public RestResponse() {}

    ...
    ...

为了简洁起见,我没有将所有导入包含在上面的原始代码中,如果我这样做的话可能会让事情变得更清楚。

我的“解析”类中有2个特定于Type类型的导入,一个是: java.lang.reflect.Type ,另一个是 {{ 3}} 即可。 TypeToken实质上暗示了反序列化过程将数据编组到的Object类型,该类型被分配给 java.lang.reflect.Type 类型的变量。

RestResponse类没有什么特别之处,需要类型导入的原因是我将编组的Type存储在名为“ java.lang.reflect.Type 类型的类成员变量中”输出”。