一直以来是做Windows C++方面的开发,但在公司目前做的是一个Web与Windows C++相结合的项目。在做Windows方面的功能时,有时需要与Web后台服务进行交互,发出相关请求以获取数据。所以当本地Windows程序出现Bug时,有部分原因是请求后台数据时导致的错误。由于是两者结合的项目,所以耦合度较大,后台有专门负责Windows客户端请求的响应。
最近Windows客户端出现请求错误,既然是与自己本职工作方面相关的问题,所以此类的后台处理便亲自来跟踪调试。通过跟踪,发现后台在处理与客户端的会话时,通过Gson这种方式把会话信息对象进行序列化保存,并在需要的时候反序列化成会话对象。虽说在校期间也学过Java,但是后来自己主攻Windows C++,所以虽然大概知道序列化的概念,但对具体内容和实现不甚了解。刚开始看到Gson这个东西时,首先想到了Json,但不十分明朗,于是到网上去查,然后才知道这是 Google提供的用来在Java对象和Json数据之间进行映射的Java类库,也就是对Json的一个封装库,是对象与Json之间的转换操作更为简便(PS:Json的知识在这里我不再讲述,可自行百度)。
为了弄懂代码意思,我在网上查了Gson的使用方法,从有限的中文资料中,发现大部分的作者在给出代码实例时,都是以Bean的形式定义对象的,每个属性都用相关的Set和Get方法,在直观的代码的影响下,我想当然的认为Gson在序列化和反序列化的时候是会调用这些方法。可是,我错了,通过验证,发现不是这样的。首先我打断点,发现根本不会触发改方法。或许是因为某种机制(Java不太熟,具体什么尚说不出来,像C++某些地方打断点就无法触发,比如有一些超时操作,打了断点该超时可能就过去了)触发不到这里,于是我修改为在代码中进行输出,结果证明,在用Gson.fromJson()反序列化生成对象时确实不会调用Set方法,也就是说,对象的属性状态不是通过这些方法来设置的(开始我还以为跟Hibernate的Bean对象类似呢)。接着我又把所有的Set和Get方法删除,发现依旧能够正常序列化和反序列化,所以就更加印证了这个事实。因具体实现不太清楚,所以无法解释这个过程是怎么实现的,但大概猜想如下:在用Gson.toJson()进行序列化时,Gson按照成员属性的声明顺序依次进行转换,最后得到Json字符串;在进行反序列化时,先创建一个对象,然后通过解析Json字串,依次填写对应属性值(此处只是一个大概过程猜想,这里有一篇介绍Gson反序列化创建对象的文章,不知可靠性高不高,大家可以参考一下 http://www.tuicool.com/articles/6FrYniN)。
最后我要说一点自己的发现:Gson反序列化时有自己的默认的数据格式,对于数字类型的数据,会默认转换为Double型,对于对象类型会转换为数组型,对于枚举类型会转换为String型,等等。举个例子:
public class MyType{
String name;
int age;
public MyType(String iName, int iAge){
name = iName;
age = iAge;
}
}
public enum PackageState {
PLAY, UPDATE, UPDATING, DOWNLOAD, DOWNLOADING,
}
public class MyCombineType{
Object myType;
int code;
Object state;
Object myNum;
public MyCombineType(MyType iMyType, int iCode, PackageState iState,,int myNum){
this.myType = iMyType;
code = iCode;
state = iState;
this.myNum = myNum;
}
}
Gson myGson = new GsonBuilder().create();
MyType myType = new MyType("ZDL", 24);
MyCombineType myCombineType = new MyCombineType(myType, 1, PackageState.PLAY, 7);
String myStr = myGson.toJson(myCombineType);
MyCombineType myCombineType1 = myGson.fromJson(myStr, MyCombineType.class);调试断点到最后一行,通过查看变量值可以看到:
myCombineType1对象的myType属性成了有两个对象的数组,分别是String型和Double型,如下图:
<img src="https://img-blog.youkuaiyun.com/20150602175129412?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWl9kb25nbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<span style="font-family: Arial, Helvetica, sans-serif;">state属性成了String类型,如下图:</span>
<span style="font-family: Arial, Helvetica, sans-serif;"><img src="https://img-blog.youkuaiyun.com/20150602175153140?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWl9kb25nbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
</span>
myNum属性成了Double类型,如下图:
<img src="https://img-blog.youkuaiyun.com/20150602175205261?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWl9kb25nbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
本文探讨了在Windows C++与Web项目中,如何使用Gson进行序列化和反序列化。作者发现Gson在转换Java对象与Json时,并不会调用Bean对象的Set方法,而是直接根据成员属性的顺序进行转换。此外,Gson在反序列化时会将数字转为Double,对象转为数组,枚举转为String等。
2373

被折叠的 条评论
为什么被折叠?



