成都工程建设信息网站,网站开发微信支付功能,商城网站开发的目的和意义,wordpress 允许评论一.Gson说明
Gson#xff08;又称Google Gson#xff09;是Google公司发布的一个开放源代码的Java库#xff0c;主要用途为序列化Java对象为JSON字符串#xff0c;或反序列化JSON字符串成Java对象。而JSON(JavaScriptObject Notation) 是一种轻量级的数据交换格式#xf…一.Gson说明
Gson又称Google Gson是Google公司发布的一个开放源代码的Java库主要用途为序列化Java对象为JSON字符串或反序列化JSON字符串成Java对象。而JSON(JavaScriptObject Notation) 是一种轻量级的数据交换格式易于人阅读和编写同时也易于机器解析和生成广泛应用于各种数据的交互中尤其是服务器与客户端的交互。 引入依赖 dependencygroupIdcom.google.code.gson/groupIdartifactIdgson/artifactIdversion2.8.5/version
/dependency二.Gson使用 2.1Gson的创建 Gson的创建方式一直接new Gson对象 // 使用new方法
Gson gson new Gson();// toJson 将bean对象转换为json字符串
String jsonStr gson.toJson(user, User.class);// fromJson 将json字符串转为bean对象
Student user gson.fromJson(jsonStr, User.class);// 序列化List
String jsonStr2 gson.toJson(list);// 反序列化成List时需要使用到TypeToken getType()
ListUser retList gson.fromJson(jsonStr2,new TypeTokenListUser(){}.getType());//type的使用User代表解析出来的Bean对象result为后台返回的json格式字符串 //List代表通过Gson按照type格式解析json格式字符串后返回的对象列表 如Type type new TypeTokenList() { }.getType(); List UserBeans gson.fromJson(result, type);
Gson的创建方式二使用GsonBuilder
使用new Gson()此时会创建一个带有默认配置选项的Gson实例如果不想使用默认配置那么就可以使用GsonBuilder。
//serializeNulls //serializeNulls()是GsonBuilder提供的一种配置当字段值为空或null时依然对该字段进行转换 Gson gson new GsonBuilder().serializeNulls().create();
使用GsonBuilder创建Gson实例的步骤
首先创建GsonBuilder,然后调用GsonBuilder提供的各种配置方法进行配置
最后调用GsonBuilder的create方法将基于当前的配置创建一个Gson实例。
GsonBuilder的一些配置 Gson gson new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() //不对没有用Expose注解的属性进行操作 .enableComplexMapKeySerialization() //当Map的key为复杂对象时,需要开启该方法 .serializeNulls() //当字段值为空或null时依然对该字段进行转换 .setDateFormat(“yyyy-MM-dd HH:mm:ss:SSS”) //时间转化为特定格式 .setPrettyPrinting() //对结果进行格式化增加换行 .disableHtmlEscaping() //防止特殊字符出现乱码 .registerTypeAdapter(User.class,new UserAdapter()) //为某特定对象设置固定的序列或反序列方式自定义Adapter需实现JsonSerializer或者JsonDeserializer接口 .create();
2.2Gson基本使用
Gson提供了fromJson() 和toJson() 两个直接用于解析和生成的方法前者实现反序列化后者实现了序列化同时每个方法都提供了重载方法
1基本数据类型的解析
Gson gson new Gson();
int i gson.fromJson(100, int.class); //100
double d gson.fromJson(\99.99\, double.class); //99.99
boolean b gson.fromJson(true, boolean.class); // true
String str gson.fromJson(String, String.class); // String2基本数据类型的生成
Gson gson new Gson();
String jsonNumber gson.toJson(100); // 100
String jsonBoolean gson.toJson(false); // false
String jsonString gson.toJson(String); //String3POJO类的生成与解析
public class User {//省略其它public String name;public int age;public String emailAddress;
}Gson gson new Gson();
User user new User(张三,24);
String jsonObject gson.toJson(user); // {name:张三kidou,age:24}解析JSON
Gson gson new Gson();
String jsonString {\name\:\张三\,\age\:24};
User user gson.fromJson(jsonString, User.class);2.3属性重命名 SerializedName 注解的使用
从上面POJO的生成与解析可以看出json的字段和值是的名称和类型是一一对应的但也有一定容错机制(如第一个例子第3行将字符串的99.99转成double型)但有时候也会出现一些不和谐的情况如
期望的json格式{“name”:“张三”,“age”:24,“emailAddress”:“zhangsanceshi.com”}
实际{“name”:“张三”,“age”:24,“email_address”:“zhangsanceshi.com”}
Gson在序列化和反序列化时需要使用反射一般各类库都将注解放到annotations包下打开源码在com.google.gson包下有一个annotations里面有一个SerializedName的注解类。对于json中email_address这个属性对应POJO的属性则变成 SerializedName(“email_address”) public String emailAddress;
为POJO字段提供备选属性名****SerializedName注解提供了两个属性上面用到了其中一个别外还有一个属性alternate接收一个String数组
注alternate需要2.4版本 SerializedName(value “emailAddress”, alternate {“email”, “email_address”}) public String emailAddress; //当三个属性(email_address、email、emailAddress)都中出现任意一个时均可以得到正确的结果
//当多种情况同时出时以最后一个出现的值为准。 Gson gson new Gson(); String json “{“name”:“张三kidou”,“age”:24,“emailAddress”:“zhangsanceshi.com”,“email”:“zhangsan_2ceshi.com”,“email_address”:“zhangsan_3ceshi.com”}”; User user gson.fromJson(json, User.class); System.out.println(user.emailAddress); // zhangsan_3example.com
2.4Gson中使用泛型
例如JSON字符串数组[“Android”,“Java”,“PHP”]
当要通过Gson解析这个json时一般有两种方式使用数组使用List而List对于增删都是比较方便的所以实际使用是还是List比较多
数组比较简单 Gson gson new Gson(); String jsonArray “[“Android”,“Java”,“PHP”]”; String[] strings gson.fromJson(jsonArray, String[].class);
对于List将上面的代码中的 String[].class 直接改为 List.class 是不行的对于Java来说List 和List 这俩个的字节码文件只一个那就是List.class这是Java泛型使用时要注意的问题 泛型擦除
为了解决的上面的问题Gson提供了TypeToken来实现对泛型的支持所以将以上的数据解析为List时需要这样写
Gson Gson gson new Gson(); String jsonArray “[“Android”,“Java”,“PHP”]”; String[] strings gson.fromJson(jsonArray, String[].class); List stringList gson.fromJson(jsonArray, new TypeTokenList() {}.getType()); //TypeToken的构造方法是protected修饰的,所以上面才会写成new TypeTokenList() {}.getType() 而不是 new TypeTokenList().getType()
泛型解析对接口POJO的设计影响
泛型的引入可以减少无关的代码 我们真正需要的data所包含的数据而code只使用一次message则几乎不用如果Gson不支持泛型或不知道Gson支持泛型的同学一定会这么定义POJO public class UserResponse { public int code; public String message; public User data; }
当其它接口的时候又重新定义一个XXResponse将data的类型改成XX很明显code和message被重复定义了多次通过泛型可以将code和message字段抽取到一个Result的类中这样只需要编写data字段所对应的POJO即可 public class Result { public int code; public String message; public T data; } //对于data字段是User时则可以写为 Result ,当是个列表的时候为 ResultList
2.5Gson的流式反序列化
1自动方式
Gson提供了fromJson()和toJson() 两个直接用于解析和生成的方法前者实现反序列化后者实现了序列化。同时每个方法都提供了重载方法 Gson.toJson(Object); Gson.fromJson(Reader,Class); Gson.fromJson(String,Class); Gson.fromJson(Reader,Type); Gson.fromJson(String,Type);
(2)手动方式手动的方式就是使用stream包下的JsonReader类来手动实现反序列化和Android中使用pull解析XML是比较类似的 String json “{“name”:“张三”,“age”:“24”}”; User user new User(); JsonReader reader new JsonReader(new StringReader(json)); reader.beginObject(); while (reader.hasNext()) { String s reader.nextName(); switch (s) { case “name”: user.name reader.nextString(); break; case “age”: user.age reader.nextInt(); //自动转换 break; case “email”: user.email reader.nextString(); break; } } reader.endObject(); // throws IOException System.out.println(user.name); //张三 System.out.println(user.age); // 24 System.out.println(user.email); //zhangsanceshi.com
自动方式最终都是通过JsonReader来实现的如果第一个参数是String类型那么Gson会创建一个StringReader转换成流操作
2.6Gson的流式序列化*
1自动方式
Gson.toJson方法列表
//PrintStream(System.out) 、StringBuilder、StringBuffer和*Writer都实现了Appendable接口。 Gson gson new Gson(); User user new User(“张三”,24,“zhangsanceshi.com”); gson.toJson(user,System.out);
(2)手动方式 JsonWriter writer new JsonWriter(new OutputStreamWriter(System.out)); writer.beginObject() // throws IOException .name(“name”).value(“张三”) .name(“age”).value(24) .name(“email”).nullValue() //演示null .endObject(); // throws IOException writer.flush(); // throws IOException //{“name”:“张三”,“age”:24,“email”:null} //除了beginObject、endObject还有beginArray和endArray两者可以相互嵌套注意配对即可。beginArray后不可以调用name方法同样beginObject后在调用value之前必须要调用name方法。
2.7使用GsonBuilder导出null值、格式化输出、日期时间
一般情况下Gson类提供的 API已经能满足大部分的使用场景但有时需要更多特殊、强大的功能时这时候就引入一个新的类 GsonBuilder。
GsonBuilder从名上也能知道是用于构建Gson实例的一个类要想改变Gson默认的设置必须使用该类配置Gson
GsonBuilder用法 //各种配置 //生成配置好的Gson Gson gson new GsonBuilder().create();
1Gson在默认情况下是不动导出值null的键的如 public class User { public String name;public int age;//省略 public String email;
} Gson gson new Gson(); User user new User(张三,24); System.out.println(gson.toJson(user)); //{“name”:“张三”,“age”:24} //email字段是没有在json中出现的当在调试时需要导出完整的json串时或API接中要求没有值必须用Null时就会比较有用。
使用方法 Gson gson new GsonBuilder().serializeNulls() .create(); User user new User(“张三”, 24); System.out.println(gson.toJson(user)); //{“name”:“张三”,“age”:24,“email”:null}
格式化输出、日期时间及其它 Gson gson new GsonBuilder() //序列化null .serializeNulls() // 设置日期时间格式另有2个重载方法 // 在序列化和反序化时均生效 .setDateFormat(“yyyy-MM-dd”) // 禁此序列化内部类 .disableInnerClassSerialization() //生成不可执行的Json多了 )]}’ 这4个字符 .generateNonExecutableJson() //禁止转义html标签 .disableHtmlEscaping() //格式化输出 .setPrettyPrinting() .create();