Gson的基本用法

Java中最常用的json类库有:JSON-Java、Gson、Jackson、FastJson等

github地址:https://github.com/google/gson

1. Gson对象

在进行序列化与反序列操作前,需要先实例化一个 com .google.gson.Gson 对象,获取 Gson 对象的方法有两种

//通过构造函数来获取
Gson gson = new Gson();
//通过 GsonBuilder 来获取,可以进行多项特殊配置
Gson gson = new GsonBuilder().create(); 

2. 生成 Json

利用 Gson 可以很方便地生成 Json 字符串,通过使用 addProperty 的四个重载方法

public static void main(String[] args) {
    JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("String", "leavesC");
    jsonObject.addProperty("Number_Integer", 23);
    jsonObject.addProperty("Number_Double", 22.9);
    jsonObject.addProperty("Boolean", true);
    jsonObject.addProperty("Char", 'c');
    System.out.println(jsonObject);
} 

3. Json与数组、List的转化

   3.1 Json数组 与 字符串数组

   

public static void main(String[] args) {
    
    Gson gson = new Gson();

    //Json数组 转为 字符串数组
    String jsonArray = "[\"https://github.com/leavesC\",\"https://www.jianshu.com/u/9df45b87cfdf\",\"Java\",\"Kotlin\",\"Git\",\"GitHub\"]";
    String[] strings = gson.fromJson(jsonArray, String[].class);
    

    //字符串数组 转为 Json数组
    jsonArray = gson.toJson(jsonArray, new TypeToken<String>() {}.getType());
    System.out.println(jsonArray);
}

  3.2 Json数组 与 List

    对于List将上面的代码中的 String[].class 直接改为 List<String>.class 是不行的,对于Java来说List<String> 和List<User> 这俩个的字节码文件只一个那就是List.class,这是Java泛型使用时要注意的问题【泛型擦除】。为了解决的上面的问题,Gson提供了TypeToken来实现对泛型的支持,所以将以上的数据解析为List<String>时需要这样写

public static void main(String[] args) {
    Gson gson = new Gson();

    String jsonArray = "[\"https://github.com/leavesC\",\"https://www.jianshu.com/u/9df45b87cfdf\",\"Java\",\"Kotlin\",\"Git\",\"GitHub\"]";

    //Json数组 转为 List
    List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
    
    //List 转为 Json数组
    jsonArray = gson.toJson(stringList, new TypeToken<List<String>>() {}.getType());
}

4.POJO类的生成与解析

//生成JSON
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);

5. 属性重命名 @SerializedName 注解

从上面POJO的生成与解析可以看出json的字段和值是的名称和类型是一一对应的,但也有一定容错机制(如第一个例子第3行将字符串的99.99转成double型),但有时候也会出现一些不和谐的情况,如:

  期望的json格式:{"name":"张三","age":24,"emailAddress":"zhangsan@ceshi.com"}

  实际:{"name":"张三","age":24,"email_address":"zhangsan@ceshi.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\":\"zhangsan@ceshi.com\",\"email\":\"zhangsan_2@ceshi.com\",\"email_address\":\"zhangsan_3@ceshi.com\"}";
User user = gson.fromJson(json, User.class);
System.out.println(user.emailAddress); // zhangsan_3@example.com

6. 使用GsonBuilder导出null值、格式化输出、日期时间

(1)Gson在默认情况下是不动导出值null的键的

Gson gson = new Gson();
User user = new User(张三",24);
System.out.println(gson.toJson(user)); //{"name":"张三","age":24}
//email字段是没有在json中出现的,当在调试时需要导出完整的json串时或API接中要求没有值必须用Null时,就会比较有用。

//使用GsonBuilder
Gson gson = new GsonBuilder().serializeNulls().create();
User user = new User("张三", 24);
System.out.println(gson.toJson(user)); //{"name":"张三","age":24,"email":null}

(2)格式化输出、日期时间及其它

Gson gson = new GsonBuilder()
    //序列化null
    .serializeNulls()
    // 设置日期时间格式,另有2个重载方法
    // 在序列化和反序化时均生效
    .setDateFormat("yyyy-MM-dd")
    // 禁此序列化内部类
     .disableInnerClassSerialization()
    //生成不可执行的Json(多了 )]}' 这4个字符)
    .generateNonExecutableJson()
     //禁止转义html标签
    .disableHtmlEscaping()
    //格式化输出
    .setPrettyPrinting()
    .create();
//:内部类(Inner Class)和嵌套类(Nested Class)的区别  

7. Type解读(附)

Type指java.lang.reflect.Type, 是Java中所有类型的公共高级接口, 代表了Java中的所有类型。

Type体系中类型的包括:数组类型(GenericArrayType)、参数化类型(ParameterizedType)、类型变量(TypeVariable)、通配符类型(WildcardType)、原始类型(Class)、基本类型(Class), 以上这些类型都实现Type接口.

参数化类型,就是我们平常所用到的泛型List、Map;

数组类型,并不是我们工作中所使用的数组String[] 、byte[],而是带有泛型的数组,即T[] ;

通配符类型, 指的是<?>, <? extends T>等等

原始类型, 不仅仅包含我们平常所指的类,还包括枚举、数组、注解等;

基本类型, 也就是我们所说的java的基本类型,即int,float,double等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值