博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gson的使用细节
阅读量:6847 次
发布时间:2019-06-26

本文共 6830 字,大约阅读时间需要 22 分钟。

关于json,gson是最常用到的一个库。 平常使用时我通常使用Gson gson = new Gson();的方式创建。 但是最近在使用木哥给的一个volley工具时,出现了解析不出来的情况,很是郁闷。 自己看了半天也没找到原因。所以专门再吧gson的使用方法总结一下。 ,哈哈,竟然有35页的开源项目。

new Gson()

我之前都是用的这种方式。。。 Gson有两个重要的方法,一个是toJson,一个是fromJson,也就是序列化和反序列化。 比如解析下面这个gson串:

{    "name" : "Ravi Tamada",     "email" : "ravi8x@gmail.com",    "phone" : {        "home" : "08947 000000",        "mobile" : "9999999999"    }    }复制代码
先写一个Userpublic class User {private String name;private String email;private Phone phone;}再写一个Phonepublic class Phone {private String home;private String mobile;}接下来一切都简单了Gson gson = new Gson();User user = gson.fromJson(response.toString(), User.class);mTextViewVolley.setText(user.getName()+"\n"+user.getEmail()+"\n"+"phone:"+user.getPhone().getHome());复制代码

gson常用的方法示例

Gson gson = new Gson();//序列化MyObject myobj = new MyObject();  String jsonstr = gson .toJson(myobj);//反序列化MyObject myobj = gson.fromJson(jsonstr, MyObject.class);  //序列化数组String[] days = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};String numbersJson = gson.toJson(days);//序列化集合List
myobjs = new ArrayList
();String jsonstr = gson.toJson(myobjs);//反序列化集合数组List
myobjs = gson.fromJson(str, new TypeToken
>(){}.getType());// DeserializationType collectionType = new TypeToken
>(){}.getType();Collection
ints2 = gson.fromJson(json, collectionType);复制代码

PS:如果需要转换的类包括泛型,那么也需要用到TypeToken,通过这个类可以获取具体的类型

注解

然而Gson并没有那么简单。他还可以使用注解:

Expose

此注解作用在属性上,表明当序列化和反序列化的时候,这个属性将会暴露给Gson对象。这个注解只有当创建Gson对象时使用GsonBuilder方式创建并调用了GsonBuilder.excludeFieldsWithoutExposeAnnotation() 方法的时候才有效,否则无效。下面是一个介绍@Expose注解如何使用的例子:

publicclass User { @Expose private String firstName; @Expose(serialize = false) private String lastName; @Expose (serialize = false, deserialize = false) private String emailAddress; private String password;}复制代码

如果你以new Gson()的方式创建Gson对象,toJson()方法和fromJson() 方法在序列化和反序列化的时候将会操作这4个属性。然而,如果你使用 Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()来创建Gson对象,Gson 的 toJson() 和 fromJson() 方法将会排除掉 password 字段,这是因为 password 字段没有被注解 @Expose 所标记。 这个 Gson 对象同样会排除 lastName 和 emailAddress 字段,因为注解@Expose的属性 serialize 被设置成了 false。类似的,Gson 将会在反序列化时排除掉 emailAddress 字段,因为 deserialize被设置成了 false。

PS: 如果不希望有某些属性,也可以使用transient屏蔽,如: transient int val;

SerializedName

用于修改属性序列化成json之后的名字。   此注解作用在属性上,表明这个属性在序列化成Json的时候,需要将名字序列化成注解的value属性指定的值。   这个注解将会覆盖任何的FieldNamingPolicy, 包括默认的命名策略。下面是一个介绍@SerializedName注解如何使用的例子:

publicclass SomeClassWithFields {    @SerializedName("name") privatefinal String someField;    private final String someOtherField;    public SomeClassWithFields(String a, String b) {      this.someField = a;      this.someOtherField = b;    }}复制代码

序列化结果是:{"name":"a","someOtherField":"b"}

Since

使用@Since注解去维护版本,比如你有一个REST的API,并且有多个版本的JSON,如果下一个版本JSON中增加了字段,但又不希望所有的版本都在使用这些字段的话,就可以使用

publicclass Example33 {    publicstaticvoid main(String[] args) {      Gson gson = new GsonBuilder().setVersion(2.0).create();      String json = gson.toJson(new ExampleClass());      System.out.println("Output for version 2.0...");      System.out.println(json);            gson= new GsonBuilder().setVersion(1.0).create();      json = gson.toJson(new ExampleClass());      System.out.println("\nOutput for version 1.0...");      System.out.println(json);            gson= new Gson();      json = gson.toJson(new ExampleClass());      System.out.println("\nOutput for No version set...");      System.out.println(json);    }  }     class ExampleClass{    String field=  "field";    // this is in version 1.0    @Since(1.0) String newField1 = "field 1";    // following will be included in the version 1.1    @Since(2.0) String newField2 = "field 2";  }  复制代码
输出为: Output for version 2.0... {"field":"field","newField1":"field 1","newField2":"field 2"} Output for version 1.0... {"field":"field","newField1":"field 1"} Output for No version set... {"field":"field","newField1":"field 1","newField2":"field 2"} 复制代码

Until

和Since相反,如果下一个版本JSON中删除了某个字段,就可以使用,原理同上。

GsonBulider

使用注释之后,我们创建gson就需要用到GsonBuilder 具体设置参数如下

Gson gson = new GsonBuilder()          .excludeFieldsWithoutExposeAnnotation() //不导出实体中没有用@Expose注解的属性          .enableComplexMapKeySerialization() //支持Map的key为复杂对象的形式          .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")//时间转化为特定格式            .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)//会把字段首字母大写,注:对于实体上使用了@SerializedName注解的不会生效.          .setPrettyPrinting() //对json结果格式化.          .setVersion(1.0)      .disableHtmlEscaping()//默认是GSON把HTML 转义的,但也可以设置不转义        .serializeNulls()//把null值也转换,默认是不转换null值的,可以选择也转换,为空时输出为{a:null},而不是{}        .create();复制代码

泛型

如果需要转换的类包括泛型,那么也需要用到TypeToken,通过这个类可以获取具体的类型

publicclass ApiResult
{ privateint ret; private String msg; private T data; publicint getRet() { return ret; } publicvoid setRet(int ret) { this.ret = ret; } public String getMsg() { return msg; } publicvoid setMsg(String msg) { this.msg = msg; } public T getData() { return data; } publicvoid setData(T data) { this.data = data; }}复制代码
ApiResult
r = GsonUtils.parse(json, new TypeToken
>() {}.getType());复制代码

解析JsonArray

以前不知道Gson可以解析JsonArray.所以使用了如下方法,想想真是无知

public static 
List
readJsonArray(JSONArray array, Class
entityType){ Gson gson =new Gson(); List
list = new ArrayList<>(); for(int i=0;i

以下是中的内容: Array Examples

Gson gson = new Gson();int[] ints = {
1, 2, 3, 4, 5};String[] strings = {
"abc", "def", "ghi"};// Serializationgson.toJson(ints); // ==> [1,2,3,4,5]gson.toJson(strings); // ==> ["abc", "def", "ghi"]// Deserializationint[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class); // ==> ints2 will be same as intsWe also support multi-dimensional arrays, with arbitrarily complex element types.复制代码

Collections Examples

Gson gson = new Gson();Collection
ints = Lists.immutableList(1,2,3,4,5);// SerializationString json = gson.toJson(ints); // ==> json is [1,2,3,4,5]// DeserializationType collectionType = new TypeToken
>(){}.getType();Collection
ints2 = gson.fromJson(json, collectionType);// ==> ints2 is same as ints复制代码

Fairly hideous: note how we define the type of collection. Unfortunately, there is no way to get around this in Java.

Collections Limitations

Can serialize collection of arbitrary objects but can not deserialize from it Because there is no way for the user to indicate the type of the resulting object While deserializing, Collection must be of a specific generic type All of this makes sense, and is rarely a problem when following good Java coding practices.

转载地址:http://dbmul.baihongyu.com/

你可能感兴趣的文章
安装了宝塔面板的服务器,一键部署私有云
查看>>
干货!14个最新优质加载动画设计,让等待成为一种享受
查看>>
Android listview与adapter用法
查看>>
Android开发之再探底部菜单TabLayout与Bottom navigation实现方式
查看>>
传瑞幸咖啡获新一轮融资,投前估值达20亿美元
查看>>
惠普集团放弃Salesforce 采用微软的云端CRM
查看>>
《DBA修炼之道:数据库管理员的第一本书》——第3章附加问题
查看>>
爱尔兰不得不接受苹果130亿欧元税款 都是欧盟逼的
查看>>
《DBA修炼之道:数据库管理员的第一本书》——3.4节概念、逻辑和物理数据模型...
查看>>
顶级智囊支招 丰泽智慧城市建设
查看>>
移动安全成头号威胁,中国NFC安全技术有望抢占国际标准制高点
查看>>
Google 宣布新开源压缩算法 Brotli
查看>>
PostgreSQL 10 GIN索引 锁优化
查看>>
《AngularJS深度剖析与最佳实践》一1.7 实战小结
查看>>
rlite —— 兼容 Redis 的嵌入式 NoSQL 引擎
查看>>
《MATLAB神经网络超级学习手册》——2.5 本章小结
查看>>
SkyNet:用开源系统管理物联网
查看>>
《Linux内核修炼之道》——1.2 内核的版本
查看>>
因为人人都作弊 Google 淘汰 Octane JS 基准测试
查看>>
《深入理解Elasticsearch(原书第2版)》一2.1 Apache Lucene默认评分公式解释
查看>>