3

我有一个使用Google Gson反序列化类的问题。这个问题困扰了我好几天,我找不到解决方案。JSON - 使用Gson反序列化客户端类

我创建了一个简单的测试情况下,这是我班的最低工作集:

import java.util.Date; 

import com.google.api.client.util.DateTime; 
import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 

public class Test { 
public static void main(String[] args) { 

    GsonBuilder builder = new GsonBuilder(); 

    Gson gson = builder.create(); 

    DateTest dt = new DateTest(new Date()); 
    String j1 = gson.toJson(dt); 
    System.out.println(j1); 
    DateTest dt2 = gson.fromJson(j1, DateTest.class); 
    System.out.println(dt2); 

} 

static class DateTest { 
    @com.google.api.client.util.Key 
    private final DateTime date; 

    public DateTest(Date dt) { 
     this.date = new DateTime(dt); 
    } 

    @Override 
    public String toString() { 
     return date.toString(); 
    } 
} 
} 

这将产生所需的输出。

序列化到: { “日期”:{ “值”:1381503448717 “dateOnly”:假 “tzShift”:60}} 反序列化回: 2013-10-11T15:57:28.717 + 01 :00

但是,我尝试序列化的类是使用“生成云端点客户端库”从Google App Engine类自动生成的(意思是我不能/不愿意修改它,但同时该类也是可序列化的/反序列化到JSON与我在类路径中的罐子 - 请参见https://developers.google.com/appengine/docs/java/endpoints/consume_android)。

经过大量的测试,我发现这个问题是自动生成的类“扩展com.google.api.client.json.GenericJson” - 如果你的代码更改为:

static class DateTest extends com.google.api.client.json.GenericJson{ 

系列化成功(与相同输出),但deserialising失败:

Exception in thread "main" java.lang.ClassCastException: Cannot cast java.util.LinkedHashMap to Test$DateTest 
at java.lang.Class.cast(Unknown Source) 
at com.google.gson.Gson.fromJson(Gson.java:643) 
at Test.main(Test.java:17) 

的Android似乎给人一种更详细的输出,这个问题是任何非基本类属性失败。

我的问题是 - 如何修改我的反序列化代码,使反序列化成功?我究竟做错了什么?

由于我的项目能够从网络反序列化相同的JSON对象,请注意,我不会接受任何类型的“尝试使用其他JSON库”的答案。

+0

请说明您实际尝试序列化/反序列化的类。 –

+0

我想反序列化DateTest,扩展GenericJson的版本 – thedayofcondor

+0

你能给我们带来一个你无法反序列化的JSON的例子吗?我运行了你的测试用例,事实上,一切正常。所以这个问题必须在JSON中给你Google。 – 4gus71n

回答

8

通过谷歌代码挖掘的一个周末后,我发现下面的代码解决了我的问题:

public static void main(String[] args) { 

    GsonFactory factory= new GsonFactory(); 

    DateTest dt = new DateTest(new Date()); 
    String j1 = factory.toString(dt); 
    System.out.println(j1); 
    DateTest dt2 = factory.fromString(j1, DateTest.class); 
    System.out.println(dt2); 

} 

希望这将帮助其他人的未来。

+0

你从哪里得到GsonFactory?什么maven artefact版本的gson?尝试了1.7.2,2.2,2.2.4,并没有找到那个类 - 只有GsonBuilder没有帮助。 – Vasile

+0

@Vasile - google-http-client-gson-x.xx.x.jar中的com.google.api.client.json.gson.GsonFactory(我相信它是在标准的AppEngine Android客户端库中) – thedayofcondor

+2

对于其他人谁绊倒了这一点,让我扩大为什么这个作品。原始代码使用'Gson',而这个新代码使用'GsonFactory'。关键区别在于Gson的包名是'com.google.gson.Gson',而GsonFactory是'com.google.api。client.json.gson.GsonFactory'。或者换句话说,它的包开始与'GenericJson'类终结点使用相同。因此,Google必须在两个Gson类之间使用稍微不同的序列化规则。 (在我的代码中,我注意到多头在Gson中被直接保存为多头,但是在GsonFactory中作为字符串。) –