赞
踩
Mavne依赖
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.2.4</version> </dependency>
Gson jar包下载地址: http://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.0/
Gson的实例化方式:
1:Gson gson=newGson();
2:通过GsonBuilder 可以配置多种选项
[java] view plain copy
Gson的基本用法:
JavaBean转换Json字符串
gson提供 publicString toJson(Object src) 方法可以将对象转换成jsonStr
[java] view plain copy
运行结果:
---->javabean convert jsonStr:{"name":"xuanyouwu","age":26}
List Map转Json字符串
[java] view plain copy
[java] view plain copy
[java] view plain copy
Json字符串转JavaBean
[java] view plain copy
运行结果:
------->json convert JavaBean:Student{name='xuanyouwu', age=26}
Json字符串转List
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
JsonPrimitive非常有意思,我们知道如果json转换成字符串 可能包含引号的转义,但是通过JsonPrimative我们可以获得为转义的字符串,看实例:
[java] view plain copy
运行结果:
------>studentJsonStr:{"name":"xuanyouwu","age":26}
------>jsonPrimitive:"{\"name\":\"xuanyouwu\",\"age\":26}"
------>jsonPrimitive:"{\"name\":\"xuanyouwu\",\"age\":26}"
------>jsonPrimitive:{"name":"xuanyouwu","age":26}
------>jsonPrimitive2:"this is String"
------>jsonPrimitive2:"this is String"
------>jsonPrimitive2:this is String
创建JsonObject
通过addPropert(key,value)可以向jsonObject中添加字段 跟hashMap类似
[java] view plain copy
运行结果:
------>create jsonObject:{"name":"xuanyouwu","age":26}
创建JsonArray
[java] view plain copy
运行结果:
------>create jsonArray:["a","b","c","d"]
JsonObject 嵌套数组或者说嵌套JsonArray
通过JsonObject的add(key,JsonElement)可以为jsonObject 添加一个数组的字段
[java] view plain copy
运行结果:
------>create jsonObject inner JsonArray:{"name":"xuanyouwu","age":26,"hobby":["骑车","打游戏","看电视"]}
Gson注解
在Gson中有五类注解
重命名注解:SerializedName
作用:转换关键字key,json转换成JavaBean时,json字段的key 默认必须和我们声明类的字段名称一样,当服务器端返回了关键字怎么办,比如key 为new switch这样,我们 在声明类的时候不能写这样的字段,可能你想服务器端改动,他可能要改数据库,但是我告诉你,做服务端的大部分不愿意改动他的json,是很自私的!这时候重命名注解都排上用场了 第二种场景:服务器端返回的json 的key 简直太丑,或者太长,你想简化,my_parent_name,可以简化成mpn 比较优雅简介
实例:
[java] view plain copy
运行结果: ------>user:User{name='zhangsan', age=26, isnew=1}
[java] view plain copy
运行结果: ------>user2:User2{name='zhangsan', age=26, pn='zhangsanf'}
作用2:结合alternate 提供多种备用字段key来解析,@SerializedName(value ="desc",alternate = {"other","note"}) 如果json中有other就会解析成desc 如果有note也会解析成desc,注意1:value中的值不能出现在alternate中,注意2:alternate的备选字段 会后面的替换前面的
实例:
[java] view plain copy
运行结果:
------>user:User{name='zhangsan', age=26, desc='成都人'}
------>user:User{name='zhangsan', age=26, desc='成都人'}
------>user:User{name='zhangsan', age=26, desc='note成都人'}
------>user:User{name='zhangsan', age=26, desc='desc成都人'}
Gson @Expose过滤注解
源码:默认既可以序列化又可以反序列化
[java] view plain copy
[java] view plain copy
[java] view plain copy
不添加@Expose注解的字段将不会解析:
分为以下几种情况:
1:不添加@Expose注解等同于@Expose(deserialize = false,serialize = false) 不做任何解析
2:@Expose(deserialize = true,serialize = false) 只解析用用,也就是反序列化可以,序列化不可以
3:@Expose(deserialize = false,serialize = true) 序列化可以,反序列化不行
4:@Expose(deserialize = true,serialize = true) 既可以序列化,也可以反序列化
实例:将分别演示这四种情况
不添加@Expose注解:等同于@Expose(deserialize = false,serialize = false)
[java] view plain copy
运行结果:
------>反序列化:User{name='null'} ------>序列化:{}
添加@Expose注解
[java] view plain copy
运行结果:
------>反序列化:User{name='zhangsan'}
------>序列化:{"name":"zhangsan2"}
@Expose注解 只序列化
[java] view plain copy
运行结果:
------>反序列化:User{name='null'}------>序列化:{"name":"zhangsan2"}
@Expose 只反序列化
[java] view plain copy
运行结果:
------>反序列化:User{name='zhangsan'}
------>序列化:{}
@Since(float v)注解 版本控制
结合GsonBuilder.setVersion(n)使用 当n>=v时 才会序列化解析
[java] view plain copy
运行结果:
------>反序列化v=1:User{name='null'}
------>序列化v=1:{}
------>反序列化v=2:User{name='zhangsan'}
------>序列化v=2:{"name":"zhangsan2"}
------>反序列化v=3:User{name='zhangsan'}
------>序列化v=3:{"name":"zhangsan2"}
@Util(float v)注解 版本控制
当gson的setVersion(n) n<v 才解析
[java] view plain copy
运行结果:
------>反序列化v=1:User{name='zhangsan'}
------>序列化v=1:{"name":"zhangsan2"}
------>反序列化v=2:User{name='null'}
------>序列化v=2:{}
------>反序列化v=3:User{name='null'}
------>序列化v=3:{}
Gson 高级用法
相信看过retrofit2.0 源码的同学都知道,其中有一个GsonConverterFactory 里面的用法十分精炼老成,这里来一段源码
据说使用TypeAdapter 效率更高,本人还未对比测试,暂时放后吧,TypeAdapter是什么玩意呢?
在源码中备注了一句 Converts Java objects to and from JSON 就是对象json之间的互相转换 接替了T 泛型类的序列化和反序列化的逻辑
从源码中我们看到区分了2.1版本之前后之后的用法,2.1版本之前可以自定义adapter:
[java] view plain copy
使用
[java] view plain copy
在2.1版本之后更推荐直接插入泛型就使用
[java] view plain copy
实例:使用TypeAdapter 来序列化和反序列化
[java] view plain copy
[java] view plain copy
[java] view plain copy
Gson的容错机制:
为什么要容错了,在javaBean中声明了int类型的age 如果服务端 返回的是"" 空字符串怎么办呢?崩溃?
如果json格式不规范如 {name=zhangsan,age:26,hobby=null} 发现不是普通的key value
容错实现方式1:
1:创建Gson的方式
[java] view plain copy
2:使用JsonReader
JsonReader jsonReader = gson.newJsonReader(value.charStream());
[java] view plain copy
3:自定义TypeAdapter
4:使用注解JsonAdapter,其实也是自定义Adapter
1.2归为一类 由框架实现,基本json大格式规范,键值对不标准,多引号的问题等等,而不报错停止解析,但是功能相对较弱
能解决bug
[java] view plain copy
3,4归为一类,都属于自定义adapter,但是3与gson绑定,4使用注解和字段绑定
实例:
[java] view plain copy
运行结果:
------->jsonFromServer:{
"age": "",
"name": "zhangsan"
}
------>默认Gson 解析 异常:com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String
------>自定义adapter 解析:User{name='zhangsan', age=0}
------>自定义adapter 解析2:User{name='zhangsan', age=0}
可以看到 age是空字符串 但是不影响整体的解析流程,这对客户端是十分友好的
基于注解的方式,上面的方式倾向于整体,注解的方式倾向于字段
[java] view plain copy
运行结果:
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
[java] view plain copy
运行结果:
------->jsonFromServer:{
"age": "",
"name": "zhangsan"
}
------> JsonDeserializer<Integer> 解析:User{name='zhangsan', age=0}
------> 默认gson 解析异常:com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String
这样定义全局的反序列化工具就能避免解析异常
保存下来 ,用作学习,不到之处,还望各位大佬指正
转载:https://blog.csdn.net/sinat_34093604/article/details/53158059
博主:吃奶的牛
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。