ImageVerifierCode 换一换
格式:DOCX , 页数:13 ,大小:20.09KB ,
资源ID:23608610      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/23608610.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Gson使用指南4.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Gson使用指南4.docx

1、Gson使用指南4注:此系列基于Gson 2.4。本次文章的主要内容: TypeAdapter JsonSerializer与JsonDeserializer TypeAdapterFactory JsonAdapter注解 TypeAdapter与 JsonSerializer、JsonDeserializer对比 TypeAdapter实例 结语 后期预告一、TypeAdapterTypeAdapter是Gson自2.0(源码注释上说的是2.1)开始版本提供的一个抽象类,用于接管某种类型的序列化和反序列化过程,包含两个注要方法write(JsonWriter,T)和read(JsonRea

2、der)其它的方法都是final方法并最终调用这两个抽象方法。12345public abstract class TypeAdapter public abstract void write(JsonWriter out, T value) throws IOException;public abstract T read(JsonReader in) throws IOException;/其它final 方法就不贴出来了,包括toJson、toJsonTree、toJson和nullSafe方法。注意:TypeAdapter 以及 JsonSerializer 和 JsonDeseria

3、lizer 都需要与GsonBuilder.registerTypeAdapter示或GsonBuilder.registerTypeHierarchyAdapter配合使用,下面将不再重复说明。使用示例:1234567User user = new User(怪盗kidou, 24);user.emailAddress = ikidou;Gson gson = new GsonBuilder()/为User注册TypeAdapter.registerTypeAdapter(User.class, new UserTypeAdapter().create();System.out.printl

4、n(gson.toJson(user);UserTypeAdapter的定义:12345678910111213141516171819202122232425262728293031323334public class UserTypeAdapter extends TypeAdapter Overridepublic void write(JsonWriter out, User value) throws IOException out.beginObject();out.name(name).value(value.name);out.name(age).value(value.age

5、);out.name(email).value(value.email);out.endObject();Overridepublic User read(JsonReader in) throws IOException User user = new User();in.beginObject();while (in.hasNext() switch (in.nextName() case name:user.name = in.nextString();break;case age:user.age = in.nextInt();break;case email:case email_a

6、ddress:case emailAddress:user.email = in.nextString();break;in.endObject();return user;当我们为User.class注册了TypeAdapter之后,只要是操作User.class那些之前介绍的SerializedName、FieldNamingStrategy、Since、Until、Expos通通都黯然失色,失去了效果,只会调用我们实现的UserTypeAdapter.write(JsonWriter, User)方法,我想怎么写就怎么写。再说一个场景,在该系列的第一篇文章就说到了Gson有一定的容错机制

7、,比如将字符串24转成int 的24,但如果有些情况下给你返了个空字符串怎么办(有人给我评论问到这个问题)?虽然这是服务器端的问题,但这里我们只是做一个示范。int型会出错是吧,根据我们上面介绍的,我注册一个TypeAdapter 把 序列化和反序列化的过程接管不就行了?123456789101112131415161718Gson gson = new GsonBuilder().registerTypeAdapter(Integer.class, new TypeAdapter() Overridepublic void write(JsonWriter out, Integer valu

8、e) throws IOException out.value(String.valueOf(value); Overridepublic Integer read(JsonReader in) throws IOException try return Integer.parseInt(in.nextString(); catch (NumberFormatException e) return -1;).create();System.out.println(gson.toJson(100); / 结果:100System.out.println(gson.fromJson(,Intege

9、r.class); / 结果:-1注:测试空串的时候一定是而不是,代表的是没有json串,才代表json里的。你说这一接管就要管两样好麻烦呀,我明明只想管序列化(或反列化)的过程的,另一个过程我并不关心,难道没有其它更简单的方法么? 当然有!就是接下来要介绍的JsonSerializer与JsonDeserializer。二、JsonSerializer与JsonDeserializerJsonSerializer和JsonDeserializer不用像TypeAdapter一样,必须要实现序列化和反序列化的过程,你可以据需要选择,如只接管序列化的过程就用JsonSerializer,只接管反

10、序列化的过程就用JsonDeserializer,如上面的需求可以用下面的代码。1234567891011121314Gson gson = new GsonBuilder().registerTypeAdapter(Integer.class, new JsonDeserializer() Overridepublic Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException try return json.getAsInt

11、(); catch (NumberFormatException e) return -1;).create();System.out.println(gson.toJson(100); /结果:100System.out.println(gson.fromJson(, Integer.class); /结果-1下面是所有数字都转成序列化为字符串的例子12345678910111213JsonSerializer numberJsonSerializer = new JsonSerializer() Overridepublic JsonElement serialize(Number src

12、, Type typeOfSrc, JsonSerializationContext context) return new JsonPrimitive(String.valueOf(src);Gson gson = new GsonBuilder().registerTypeAdapter(Integer.class, numberJsonSerializer).registerTypeAdapter(Long.class, numberJsonSerializer).registerTypeAdapter(Float.class, numberJsonSerializer).registe

13、rTypeAdapter(Double.class, numberJsonSerializer).create();System.out.println(gson.toJson(100.0f);/结果:100.0注:registerTypeAdapter必须使用包装类型,所以int.class,long.class,float.class和double.class是行不通的。同时不能使用父类来替上面的子类型,这也是为什么要分别注册而不直接使用Number.class的原因。上面特别说明了registerTypeAdapter不行,那就是有其它方法可行咯?当然!换成registerTypeHie

14、rarchyAdapter就可以使用Number.class而不用一个一个的当独注册啦!registerTypeAdapter与registerTypeHierarchyAdapter的区别:registerTypeAdapterregisterTypeHierarchyAdapter支持泛型是否支持继承否是注:如果一个被序列化的对象本身就带有泛型,且注册了相应的TypeAdapter,那么必须调用Gson.toJson(Object,Type),明确告诉Gson对象的类型。123456789101112Type type = new TypeTokenList() .getType();Ty

15、peAdapter typeAdapter = new TypeAdapterList() /略;Gson gson = new GsonBuilder().registerTypeAdapter(type, typeAdapter).create();List list = new ArrayList();list.add(new User(a,11);list.add(new User(b,22);/注意,多了个type参数String result = gson.toJson(list, type);三、TypeAdapterFactoryTypeAdapterFactory,见名知意,

16、用于创建TypeAdapter的工厂类,通过对比Type,确定有没有对应的TypeAdapter,没有就返回null,与GsonBuilder.registerTypeAdapterFactory配合使用。12345678Gson gson = new GsonBuilder().registerTypeAdapterFactory(new TypeAdapterFactory() Overridepublic TypeAdapter create(Gson gson, TypeToken type) return null;).create();四、JsonAdapter注解JsonAdap

17、ter相较之前介绍的SerializedName、FieldNamingStrategy、Since、Until、Expos这几个注解都是比较特殊的,其它的几个都是用在POJO的字段上,而这一个是用在POJO类上的,接收一个参数,且必须是TypeAdpater,JsonSerializer或JsonDeserializer这三个其中之一。上面说JsonSerializer和JsonDeserializer都要配合GsonBuilder.registerTypeAdapter使用,但每次使用都要注册也太麻烦了,JsonAdapter就是为了解决这个痛点的。使用方法(以User为例):123456

18、789101112131415161718JsonAdapter(UserTypeAdapter.class) /加在类上public class User public User() public User(String name, int age) this.name = name;this.age = age;public User(String name, int age, String email) this.name = name;this.age = age;this.email = email;public String name;public int age;Serializ

19、edName(value = emailAddress)public String email;使用时不用再使用GsonBuilder去注册UserTypeAdapter了。注:JsonAdapter仅支持TypeAdapter或TypeAdapterFactory12345Gson gson = new Gson();User user = new User(怪盗kidou, 24, ikidou);System.out.println(gson.toJson(user);/结果:name:怪盗kidou,age:24,email:ikidou/为区别结果,特意把email字段与Serial

20、izedName注解中设置的不一样注意:JsonAdapter的优先级比GsonBuilder.registerTypeAdapter的优先级更高。五、TypeAdapter与 JsonSerializer、JsonDeserializer对比TypeAdapterJsonSerializer、JsonDeserializer引入版本2.01.xStream API支持不支持*,需要提前生成JsonElement内存占用小比TypeAdapter大效率高比TypeAdapter低作用范围序列化和反序列化序列化或反序列化六、TypeAdapter实例注:这里的TypeAdapter泛指TypeA

21、dapter、JsonSerializer和JsonDeserializer。这里的TypeAdapter 上面讲了一个自动将 字符串形式的数值转换成int型时可能出现 空字符串的问题,下面介绍一个其它读者的需求:服务器返回的数据中data字段类型不固定,比如请求成功data是一个List,不成功的时候是String类型,这样前端在使用泛型解析的时候,怎么去处理呢?其实这个问题的原因主要由服务器端造成的,接口设计时没有没有保证数据的一致性,正确的数据返回姿势:同一个接口任何情况下不得改变返回类型,要么就不要返,要么就返空值,如null、,。但这里还是给出解决方案:方案一:12345678910

22、111213Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(List.class, new JsonDeserializerList() Overridepublic List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException if (json.isJsonArray()/这里要自己负责解析了Gson newGson = new Gson();return newG

23、son.fromJson(json,typeOfT);else /和接口类型不符,返回空Listreturn Collections.EMPTY_LIST;).create();方案二:12345678910111213141516171819Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(List.class, new JsonDeserializerList() Overridepublic List deserialize(JsonElement json, Type typeOfT, JsonDeserializat

24、ionContext context) throws JsonParseException if (json.isJsonArray() JsonArray array = json.getAsJsonArray();Type itemType = (ParameterizedType) typeOfT).getActualTypeArguments()0;List list = new ArrayList();for (int i = 0; i array.size(); i+) JsonElement element = array.get(i);Object item = context

25、.deserialize(element, itemType);list.add(item);return list; else /和接口类型不符,返回空Listreturn Collections.EMPTY_LIST;).create();要注意的点: 必须使用registerTypeHierarchyAdapter方法,不然对List的子类无效,但如果POJO中都是使用List,那么可以使用registerTypeAdapter。 对于是数组的情况,需要创建一个新的Gson,不可以直接使用context,不然gson又会调我们自定义的JsonDeserializer造成递归调用,方案二没有重新创建Gson,那么就需要提取出List中E的类型,然后分别反序列化

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1