整了两天,我C,不得不骂一句,这该死的代码!!!
我遇到的问题就是用Gson序列化和反序列化对象以及对象的List过程中反序列化出错。
其实,最近在做一个同步的项目,客户端和云端都有一个相同的对象,基于GAE的云端对象的序列化和反序列化完全正常,就TM的在客户端有异常,不是我脾气暴,这实
在是太让人无奈了,反复的测啊测啊,试啊试啊,唉,java真是开源的么???
先说解决方案,咱再看问题。
解决方案:实体类中必须要有一个无参构造函数;而且绝对不能有太特别参数的
构造函数,例如Cursor类型的作为参数。
先贴代码
一、实体类BabyInfo.java:
package test
import android.database.Cursor;
import test.EnumManager.Gender;
import test.EnumManager.IsDelete;
public class BabyInfo {
private int babyID;
private String babyName;
private long birthDate;
private Gender gender;
private long createTime;
private long updateTime;
private String imgUri;
private float weight;
private float height;
private String note;
private IsDelete isDelete;
public BabyInfo(int babyID, String babyName, long birthDate, Gender gender,
long createTime, long updateTime, String imgUri, float weight,
float height, String note) {
super();
this.babyID = babyID;
this.babyName = babyName;
this.birthDate = birthDate;
this.gender = gender;
this.createTime = createTime;
this.updateTime = updateTime;
this.imgUri = imgUri;
this.weight = weight;
this.height = height;
this.note = note;
}
public BabyInfo(Cursor cursor) {
this.babyID = cursor.getInt(0);
this.babyName = cursor.getString(1);
this.birthDate = cursor.getLong(2);
this.gender = cursor.getShort(3) == 0 ? Gender.BOY : Gender.GIRL;
this.createTime = cursor.getLong(4);
this.updateTime = cursor.getLong(5);
this.imgUri = cursor.getString(6);
this.weight = cursor.getFloat(7);
this.height = cursor.getInt(8);
this.note = cursor.getString(9);
this.isDelete=cursor.getShort(10)==0?IsDelete.FALSE:IsDelete.TRUE;
}
public int getBabyID() {
return babyID;
}
public void setBabyID(int babyID) {
this.babyID = babyID;
}
public String getBabyName() {
return babyName;
}
public void setBabyName(String babyName) {
this.babyName = babyName;
}
public long getBirthDate() {
return birthDate;
}
public void setBirthDate(long birthDate) {
this.birthDate = birthDate;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public long getUpdateTime() {
return updateTime;
}
public void setUpdateTime(long updateTime) {
this.updateTime = updateTime;
}
public String getImgUri() {
return imgUri;
}
public void setImgUri(String imgUri) {
this.imgUri = imgUri;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public void setNote(String note) {
this.note = note;
}
public String getNote() {
return note;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Gender getGender() {
return gender;
}
public void setIsDelete(IsDelete isDelete) {
this.isDelete = isDelete;
}
public IsDelete getIsDelete() {
return isDelete;
}
}
此对象就是一个婴儿信息,定义一些属性,然后构造函数,然后是一些get和set。
package test;
import java.lang.reflect.Type;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class BabyDataSerialiseHelper {
public List<BabyInfo> fromJson_BabyInfoList(String jsonStr){
Type type=new TypeToken<List<BabyInfo> >() {}.getType();
List<BabyInfo> babyInfos=new Gson().fromJson(jsonStr, type);
return babyInfos;
}
public BabyInfo fromJson_BabyInfo(String jsonStr) {
Type type=new TypeToken<BabyInfo>() {}.getType();
BabyInfo babyInfo=new Gson().fromJson(jsonStr, type);
return babyInfo;
}
public String toJson(Object obj) {
Gson gson=new Gson();
String reString=gson.toJson(obj);
return reString;
}
}
这个里面提供了将对象序列化成字符串toJson()和从字符串反序列化成对象fromJson_BabyInfo()或者对象的List集合fromJson_BabyInfoList()的方法。
三、测试类BabyDataSerialiseHelperTest.java:
package test;
import java.util.LinkedList;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import test.EnumManager.Gender;
import test.EnumManager.IsDelete;
public class BabyDataSerialiseHelperTest {
public BabyDataSerialiseHelper babyDataSerialiseHelper=new BabyDataSerialiseHelper();
@Test
public void unserialiseBabyInfoList() throws Exception {
BabyInfo babyInfo=new BabyInfo
(1, "hello", 125023156, Gender.BOY, 12501362, 125544122, "aa.jpg", 20, 25, "dsafdsafsa");
List<BabyInfo> infoList=new LinkedList<BabyInfo>();
infoList.add(babyInfo);
infoList.add(babyInfo);
String jsonBabyInfo= babyDataSerialiseHelper.toJson(babyInfo);
System.out.println(jsonBabyInfo);
String jsonBabyinfosString=babyDataSerialiseHelper.toJson(infoList);
System.out.print(jsonBabyinfosString);
BabyInfo info3=babyDataSerialiseHelper.fromJson_BabyInfo(jsonBabyInfo);
System.out.println(info3.getBabyName());
List<BabyInfo> babyInfos2=babyDataSerialiseHelper.fromJson_BabyInfoList(jsonBabyinfosString);
System.out.println(babyInfos2.size());
}
}
这里面就是定义BabyInfo对象和List<BabyInfo>对象,然后序列化和反序列化,
打印出结果。
可是总是不行,反序列化BabyInfo和List<BabyInfo>对象时就是出错,而且还不
抛
出异常呢,异常直接被隐藏掉了。悲催欲死啊。
经过反复比较和调换,才知道,实体类中少了个无参构造函数,而且多了个
Cursor
类型的构造函数,唉,鬼知道是这个原因啊,网上搜的都不靠谱,就一个
提到要用无
参构造函数的,可是还是错,鬼知道Cursor形参的构造函数也会错啊。