Android中的JSON到Java对象不能与GSON一起使用

use*_*599 1 java android json google-api gson

我试图将一些JSON转换为android中的java对象,但它似乎不起作用.

Gson gson = new Gson();
Person person = gson.fromJson(s, Person.class);
Toast toast = Toast.makeText(getApplicationContext(), "Welcome back " + person.getDisplayName(), duration);
toast.show();
Run Code Online (Sandbox Code Playgroud)

Person.class的地方

com.google.api.services.plus.model.Person
Run Code Online (Sandbox Code Playgroud)

我收到类型转换错误,例如:

wrong object type: Ljava/lang/Double; Ljava/lang/Integer;
java.lang.IllegalArgumentException: invalid value for field
Run Code Online (Sandbox Code Playgroud)

但是我想从API库中重用这个模型对象,所以无论如何要解决这个问题吗?

编辑:

要以更简单的形式证明此问题,请参阅此示例.

com.google.api.services.plus.model.Person;

Gson g = new Gson();

    Person p1 = new Person();
    p1.setDisplayName("Test");
    p1.setCircledByCount(10);

    String json = g.toJson(p1);
    Person fromJson = g.fromJson(json, Person.class);
    System.out.println(fromJson.getDisplayName());
Run Code Online (Sandbox Code Playgroud)

抛出相同的异常.

Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.google.api.services.plus.model.Person.circledByCount to java.lang.Double
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?谢谢

Bri*_*ach 6

问题是你正在使用的类并不意味着/设计用于Gson.

核心问题是,Person扩展GenericJson延伸GenericData延伸AbstractMap<String, Object>...而就是问题所在.

当Gson尝试反序列化JSON时,它正在使用它MapTypeAdapterFactory,不幸的是,它使得JSON数字类型在Java中"circledByCount"被读取Double.

然后,这个Person类的复杂性就开始了.如果你去查看源代码,它实际上使用注释和重写put方法填充该字段Person.如果查看堆栈跟踪,您实际上可以看到发生了什么:

Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.google.api.services.plus.model.Person.circledByCount to java.lang.Double
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
    at java.lang.reflect.Field.set(Field.java:680)
    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:803)
    at com.google.gson.Gson.fromJson(Gson.java:768)
    at com.google.gson.Gson.fromJson(Gson.java:717)
    at com.google.gson.Gson.fromJson(Gson.java:689)
Run Code Online (Sandbox Code Playgroud)

GSON呼吁GenericDataput()方法(因为,它知道这是个Map).该方法实际上circledByCount通过反射填充带注释的字段.而且......这是错误的类型.

所以,基本上......这不适用于Gson.至少不是没有编写自定义JsonDeserializer而是看着课程,这将是相当复杂的.