gson读取json字符串_Gson 中的一个坑

Gson 是谷歌出品的 json 库,功能强大,也很安全,很少出现安全漏洞,使用的很广泛。Gson 对类型要求的很严格,所以才比较少出现安全漏洞。

但 Gson 使用起来也比较繁琐,没有 fastjson 之类的类库使用起来那么简单,本文介绍一些使用 Gson 在处理字符串类型时需要注意的事项。

?

本文基于 Gson 2.8.6

先来看段代码:

Gson gson = new Gson();HashMap<String, String> data = new HashMap<>();data.put("ray", "jun");String jsonString = gson.toJson(data);JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);String str = String.valueOf(jsonObject.get("ray"));assertTrue((str).equals("jun")); // false

上面的代码输出的结果是 false

再看下面的这段代码:

Gson gson = new Gson();HashMap<String, Integer> data = new HashMap<>();data.put("ray", 18);String jsonString = gson.toJson(data);JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);Integer integer = Integer.valueOf(String.valueOf(jsonObject.get("ray")));assertTrue(integer == 18); // true

上面的代码输出的结果是 true。这两段代码基本一样,在结果上却不同,下面来看看问题出在哪里。

下面把第一段代码中两个值都打印出来:

String str = String.valueOf(jsonObject.get("ray"));System.out.println("jun");System.out.println(str);
jun"jun"

第二个值明显和预期的不一样,问题就出在这里。

JsonObject 的 get 方法返回的是一个 JsonElement 的类型,JsonObject 也实现了这个类型,是 Gson 中所有类型的父类。

在上面的代码中,如果直接对 JsonElement 类型使用 String.valueOf,就会调用 JsonElement 方法的 toString 方法,大概代码如下:

StringWriter stringWriter = new StringWriter();JsonWriter jsonWriter = new JsonWriter(stringWriter);jsonWriter.setLenient(true);Streams.write(this, jsonWriter);return stringWriter.toString();

相当于会把当前的元素放入 StringWriter 中,然后再调用 StringWriter 的 toString 方法,获得结果。

到这里都没有问题,问题的关键在于对于字符串类型的值,在 JsonElement 中存储时,会在外面再加上一层引号。

所以字符串 "jun" 会被存储为 ""jun"",所以如果直接使用 toString 方法获得值时,字符串会多一层引号。

对于其他非字符串类型的值,在调用 valueOf 时,反而可以获取到正确的值。

但上面的用法其实都是错误的,如果需要获取特定的值,还是应该使用 Gson 提供的 getAsxx 系列方法。

文 / Rayjun

e380342b7e7e2b9d36006b8bc950bbc5.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值