【问题标题】:java.lang.IllegalArgumentException while deserializing JSON through GSON通过 GSON 反序列化 JSON 时出现 java.lang.IllegalArgumentException
【发布时间】:2017-03-04 09:26:58
【问题描述】:

我有一个模型类,我想通过 GSON 对其进行序列化/反序列化,同时将其发送到 Android 服务:

public final class SearchTutorsQuery extends com.google.api.client.json.GenericJson {
    @com.google.api.client.util.Key
    private com.learncity.searchApi.model.LatLng location;
    @com.google.api.client.util.Key
    private java.util.List<java.lang.String> subjects;
    @com.google.api.client.util.Key
    private com.learncity.searchApi.model.TutorProfileResponseView tutorProfileResponseView;
    @com.google.api.client.util.Key
    private java.util.List<java.lang.String> tutorTypes;

    public SearchTutorsQuery() { /* compiled code */ }

}

我在反序列化 JSON 字符串时遇到异常:

java.lang.IllegalArgumentException: field com.learncity.searchApi.model.SearchTutorsQuery.tutorProfileResponseView has type com.learncity.searchApi.model.TutorProfileResponseView, got com.google.gson.internal.LinkedTreeMap
                      at java.lang.reflect.Field.set(Native Method)
                      at com.google.api.client.util.FieldInfo.setFieldValue(FieldInfo.java:245)
                      at com.google.api.client.util.FieldInfo.setValue(FieldInfo.java:206)
                      at com.google.api.client.util.GenericData.put(GenericData.java:103)
                      at com.google.api.client.util.GenericData.put(GenericData.java:47)
                      at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:188)
                      at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
                      at com.google.gson.Gson.fromJson(Gson.java:887)
                      at com.google.gson.Gson.fromJson(Gson.java:852)
                      at com.google.gson.Gson.fromJson(Gson.java:801)
                      at com.google.gson.Gson.fromJson(Gson.java:773)
                      at com.learncity.learner.search.SearchService$SearchHandler.handleMessage(SearchService.java:66)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6077)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

这是给出异常的 TutorProfileResponseView:

public final class TutorProfileResponseView extends com.google.api.client.json.GenericJson {
    @com.google.api.client.util.Key
    private java.lang.Integer disciplines;
    @com.google.api.client.util.Key
    private com.learncity.searchApi.model.EducationalQualificationResponseView educationalQualification;
    @com.google.api.client.util.Key
    private com.learncity.searchApi.model.EducationalQualificationResponseView educationalQualifications;
    @com.google.api.client.util.Key
    private java.lang.Integer global;
    @com.google.api.client.util.Key
    private java.lang.Integer mCurrentStatus;
    @com.google.api.client.util.Key
    private java.lang.Integer mDisplayPicturePath;
    @com.google.api.client.util.Key
    private java.lang.Integer mEmailID;
    @com.google.api.client.util.Key
    private com.learncity.searchApi.model.LatLngResponseView mLastKnownGeoCoordinates;
    @com.google.api.client.util.Key
    private java.lang.Integer mName;
    @com.google.api.client.util.Key
    private java.lang.Integer mPassword;
    @com.google.api.client.util.Key
    private java.lang.Integer mPhoneNo;
    @com.google.api.client.util.Key
    private java.lang.Integer nil;
    @com.google.api.client.util.Key
    private com.learncity.searchApi.model.OccupationResponseView occupation;
    @com.google.api.client.util.Key
    private java.lang.Integer rating;
    @com.google.api.client.util.Key
    private com.learncity.searchApi.model.CreditsResponseView teachingCredits;
    @com.google.api.client.util.Key
    private java.lang.Integer tutorTypes;

    public TutorProfileResponseView() { /* compiled code */ }
}

如果你想知道,com.google.api.client.json.GenericJson 的类层次结构是:

java.lang.Object
    java.util.AbstractMap<String,Object>
        com.google.api.client.util.GenericData
            com.google.api.client.json.GenericJson 

我已尝试将以下 2 条规则放入 proguard 文件中:

-keep class com.google.gson.stream.** { *; }
-keep class com.learncity.searchApi.model.** { *; }

有人知道我错过了什么吗?

【问题讨论】:

  • 删除扩展并重试。
  • @Mehdi :这就是问题所在:这是由 Google 客户端 API 生成器生成的代码。我不能插手这些课程。
  • 听起来与stackoverflow.com/questions/42553204/… 非常相似。你的 ProGuard 配置文件中有-keepattributes Signature 吗?

标签: java android json gson


【解决方案1】:

直观地看问题,它不应该存在,但 java.util.AbstractMap&lt;String,Object&gt; 类在这里有转折。我为 Gson 尝试了自定义 TypeAdapter,但没有成功。我本可以编写一个自定义的反序列化器,但是随着我的数据模型的变化,那时我将需要处理一个新的依赖关系,因此自定义反序列化器远非理想的解决方案。除了我自己的从java.util.AbstractMap&lt;String,Object&gt; 扩展的类之外,我试图找出所有问题。您可以看到它具有 Object 作为类型参数,允许将任何内容放入地图中。没有类型信息。呈现(根据类),Gson 或任何其他 JSON 反序列化器可以用来找出正确的类型。

现在的解决方案是 - 没有使用 Gson 或 JSON 反序列化器的解决方案,但这表明您必须更改模型结构或更改应用程序中的其他一些设计决策。我最终对设计进行了更改以解决此问题。

当然,如果您事先知道类型,TypeAdapter 或反序列化器可能会解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多