使用GSON库转换Java对象为JSON对象的进阶实例详解
对List和map等结构的常用转换操作基本上可以满足我们处理的绝大多数需求,但有时项目中对json有特殊的格式规定.比如下面的json串解析:
[{"tableName":"students","tableData":[{"id":1,"name":"李坤","birthDay":"Jun22,20129:54:49PM"},{"id":2,"name":"曹贵生","birthDay":"Jun22,20129:54:49PM"},{"id":3,"name":"柳波","birthDay":"Jun22,20129:54:49PM"}]},{"tableName":"teachers","tableData":[{"id":1,"name":"米老师","title":"教授"},{"id":2,"name":"丁老师","title":"讲师"}]}]
分析之后我们发现普通的方式都不好处理上面的json串.请看本文是如何处理的吧:
实体类:
importjava.util.Date; publicclassStudent{ privateintid; privateStringname; privateDatebirthDay; publicintgetId(){ returnid; } publicvoidsetId(intid){ this.id=id; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicDategetBirthDay(){ returnbirthDay; } publicvoidsetBirthDay(DatebirthDay){ this.birthDay=birthDay; } @Override publicStringtoString(){ return"Student[birthDay="+birthDay+",id="+id+",name=" +name+"]"; } } publicclassTeacher{ privateintid; privateStringname; privateStringtitle; publicintgetId(){ returnid; } publicvoidsetId(intid){ this.id=id; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicStringgetTitle(){ returntitle; } publicvoidsetTitle(Stringtitle){ this.title=title; } @Override publicStringtoString(){ return"Teacher[id="+id+",name="+name+",title="+title +"]"; } }
注意这里定义了一个TableData实体类:
importjava.util.List; publicclassTableData{ privateStringtableName; privateListtableData; publicStringgetTableName(){ returntableName; } publicvoidsetTableName(StringtableName){ this.tableName=tableName; } publicListgetTableData(){ returntableData; } publicvoidsetTableData(ListtableData){ this.tableData=tableData; } }
测试类:
(仔细看将json转回为对象的实现,这里经过两次转化,第一次转回的结果是map不是我们所期望的对象,对map再次转为json后再转为对象,我引用的是Gson2.1的jar处理正常,好像使用Gson1.6的jar会报错,所以建议用最新版本)
importjava.util.ArrayList; importjava.util.Date; importjava.util.List; importcom.google.gson.Gson; importcom.google.gson.reflect.TypeToken; publicclassGsonTest5{ /** *@paramargs */ publicstaticvoidmain(String[]args){ //对象转为Json-->start Studentstudent1=newStudent(); student1.setId(1); student1.setName("李坤"); student1.setBirthDay(newDate()); Studentstudent2=newStudent(); student2.setId(2); student2.setName("曹贵生"); student2.setBirthDay(newDate()); Studentstudent3=newStudent(); student3.setId(3); student3.setName("柳波"); student3.setBirthDay(newDate()); List<Student>stulist=newArrayList<Student>(); stulist.add(student1); stulist.add(student2); stulist.add(student3); Teacherteacher1=newTeacher(); teacher1.setId(1); teacher1.setName("米老师"); teacher1.setTitle("教授"); Teacherteacher2=newTeacher(); teacher2.setId(2); teacher2.setName("丁老师"); teacher2.setTitle("讲师"); List<Teacher>teacherList=newArrayList<Teacher>(); teacherList.add(teacher1); teacherList.add(teacher2); TableDatatd1=newTableData(); td1.setTableName("students"); td1.setTableData(stulist); TableDatatd2=newTableData(); td2.setTableName("teachers"); td2.setTableData(teacherList); List<TableData>tdList=newArrayList<TableData>(); tdList.add(td1); tdList.add(td2); Gsongson=newGson(); Strings=gson.toJson(tdList); System.out.println(s); //结果:[{"tableName":"students","tableData":[{"id":1,"name":"李坤","birthDay":"Jun22,201210:44:16AM"},{"id":2,"name":"曹贵生","birthDay":"Jun22,201210:44:16AM"},{"id":3,"name":"柳波","birthDay":"Jun22,201210:44:16AM"}]},{"tableName":"teachers","tableData":[{"id":1,"name":"米老师","title":"教授"},{"id":2,"name":"丁老师","title":"讲师"}]}] //对象转为Json-->end /////////////////////////////////////////////////////////////////////// //将json转为数据-->start List<TableData>tableDatas2=gson.fromJson(s, newTypeToken<List<TableData>>(){ }.getType()); for(inti=0;i<tableDatas2.size();i++){ TableDataentityData=tableDatas2.get(i); StringtableName=entityData.getTableName(); ListtableData=entityData.getTableData(); Strings2=gson.toJson(tableData); //System.out.println(s2); //System.out.println(entityData.getData()); if(tableName.equals("students")){ System.out.println("students"); List<Student>retStuList=gson.fromJson(s2, newTypeToken<List<Student>>(){ }.getType()); for(intj=0;j<retStuList.size();j++){ System.out.println(retStuList.get(j)); } }elseif(tableName.equals("teachers")){ System.out.println("teachers"); List<Teacher>retTchrList=gson.fromJson(s2, newTypeToken<List<Teacher>>(){ }.getType()); for(intj=0;j<retTchrList.size();j++){ System.out.println(retTchrList.get(j)); } } } //Json转为对象-->end } }
输出结果:
[{"tableName":"students","tableData":[{"id":1,"name":"李坤","birthDay":"Jun22,201210:04:12PM"},{"id":2,"name":"曹贵生","birthDay":"Jun22,201210:04:12PM"},{"id":3,"name":"柳波","birthDay":"Jun22,201210:04:12PM"}]},{"tableName":"teachers","tableData":[{"id":1,"name":"米老师","title":"教授"},{"id":2,"name":"丁老师","title":"讲师"}]}] students Student[birthDay=FriJun2222:04:12CST2012,id=1,name=李坤] Student[birthDay=FriJun2222:04:12CST2012,id=2,name=曹贵生] Student[birthDay=FriJun2222:04:12CST2012,id=3,name=柳波] teachers Teacher[id=1,name=米老师,title=教授] Teacher[id=2,name=丁老师,title=讲师]
注册TypeAdapter及处理Enum类型
枚举类型给我们的程序带来了好处,如何用Gson来实现与Json的互转呢?请看本文.
本文重点掌握如何自己写一个TypeAdapter及注册TypeAdapter和处理Enum类型.
实体类:
publicenumPackageState{ PLAY,UPDATE,UPDATING,DOWNLOAD,DOWNLOADING, } publicclassPackageItem{ privateStringname; privatePackageStatestate; privateStringsize; publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicPackageStategetState(){ returnstate; } publicvoidsetState(PackageStatestate){ this.state=state; } publicStringgetSize(){ returnsize; } publicvoidsetSize(Stringsize){ this.size=size; } @Override publicStringtoString(){ return"PackageItem[name="+name+",size="+size+",state=" +state+"]"; } }
自己写一个转换器实现JsonSerializer<T>接口和jsonDeserializer<T>接口:
importjava.lang.reflect.Type; importcom.google.gson.JsonDeserializationContext; importcom.google.gson.JsonDeserializer; importcom.google.gson.JsonElement; importcom.google.gson.JsonParseException; importcom.google.gson.JsonPrimitive; importcom.google.gson.JsonSerializationContext; importcom.google.gson.JsonSerializer; publicclassEnumSerializerimplementsJsonSerializer<PackageState>, JsonDeserializer<PackageState>{ //对象转为Json时调用,实现JsonSerializer<PackageState>接口 @Override publicJsonElementserialize(PackageStatestate,Typearg1, JsonSerializationContextarg2){ returnnewJsonPrimitive(state.ordinal()); } //json转为对象时调用,实现JsonDeserializer<PackageState>接口 @Override publicPackageStatedeserialize(JsonElementjson,TypetypeOfT, JsonDeserializationContextcontext)throwsJsonParseException{ if(json.getAsInt()<PackageState.values().length) returnPackageState.values()[json.getAsInt()]; returnnull; } }
测试类:
importcom.google.gson.Gson; importcom.google.gson.GsonBuilder; publicclassGsonTest6{ publicstaticvoidmain(String[]args){ GsonBuildergsonBuilder=newGsonBuilder(); gsonBuilder.registerTypeAdapter(PackageState.class, newEnumSerializer()); Gsongson=gsonBuilder.create(); PackageItemitem=newPackageItem(); item.setName("item_name"); item.setSize("500M"); item.setState(PackageState.UPDATING);//这个state是枚举值 Strings=gson.toJson(item); System.out.println(s); System.out.println("--------------------------------"); PackageItemretItem=gson.fromJson(s,PackageItem.class); System.out.println(retItem); } }
输出结果(结果中已经将state的对应枚举类型转为了int类型):
{"name":"item_name","state":2,"size":"500M"} -------------------------------- PackageItem[name=item_name,size=500M,state=UPDATING]