2012-05-12 40 views
1

我在GSON-JSON中遇到了一些问题。GSON-JSON反序列化类中的对象

我们看到下面的代码:

public static class ProtoQuery { 
    public String action; 
    public String token; 
    public Object params; 

    public ProtoQuery(String action, String token, Object params) { 
     this.action = action; 
     this.token = token; 
     this.params = params; 
    } 
} 


// Authentication Phase 
public static class ProtoAuth { 
    public String username; 
    public String password; 

    public ProtoAuth(String username, String password) { 
     this.username = username; 
     this.password = password; 
    } 
} 


    // Serialize Object 
    Gson gson = new Gson(); 
    ProtoQuery tmp = new ProtoQuery("ProtoAuth", "", new JirckeProtocol.ProtoAuth("ABC", "myPASS")); 
    String json = gson.toJson(tmp); 

    // Deserialize Object 
    ProtoQuery deserializedOBJ = gson.fromJson(json, ProtoQuery.class); 

问题就在这里: deserializedOBJ.object返回LinkedHashMap中。 我想转换回ProtoAuth对象..我怎么知道这是一个ProtoAuth?在ProtoQuery中使用“action”参数。

我需要这样的东西 deserializedOBJ.params = gson.fromJSON(json.object,ProtoAuth.class)

什么是做到这一点的最好方法是什么? 还有一种方法可以做到这一点,无需编写我自己的序列化器/ deserialer?

其实我使用该代码:

deserializedOBJ.params = gson.fromJson(element, Class.forName("MyProtocol$ProtoAuth")); 
+0

我想你不能将params声明为“ProtoAuth”? –

+0

不,因为参数可以是ProtoAuth,ProtoReq,ProtoStatus,ProtoEcc ...我将我的查询包装在类中,我认为它对于更好的文档是有用的(外部开发人员可以读取Protocol.java和内部类并知道什么请求和每个查询的参数) – Kaiser69

回答

6

我会键入ProtoQuery如下:

public static class ProtoQuery<T> { 
    public String action; 
    public String token; 
    public T params; 

    public ProtoQuery(String action, String token, T params) { 
     this.action = action; 
     this.token = token; 
     this.params = params; 
    } 
} 


// Authentication Phase 
public static class ProtoAuth { 
    public String username; 
    public String password; 

    public ProtoAuth(String username, String password) { 
     this.username = username; 
     this.password = password; 
    } 
} 

与类型ProtoAuth的参数去反序列化,您可以拨打如下:

Type type = new TypeToken<ProtoQuery<ProtoAuth>>() {}.getType(); 
ProtoQuery<ProtoAuth> deserializedOBJ = gson.fromJson(json, type); 
+0

非常优雅的+1(垫) – ant

+1

嗯...在这种情况下,你知道在编译时的TYPE,在我的情况下我不知道,所以我必须使用它:Type type = new TypeToken >(){} .getType(); - 无论如何,我认为这个解决方案很简单,并且工作得很好。另一个小问题,如果ProtoAuth也包含另一个类型(字符串用户/通过用UserInfo对象替代),我可以反序列化没有问题吗? – Kaiser69

+0

@ Kaiser69您可以用GSon来完成您想要反序列化JSon字符串的任何事情。唯一的限制是在反序列化过程中:GSon必须知道将被反序列化的类型。因此,如果您的字段使用UserInfo键入,则不会有问题。如果输入超类或超界面,那么你会遇到一些问题。这些问题可以通过使用TypeAdapter来解决。 –