本文详细介绍了Gson库在Java中的使用,包括对象转json、json转对象、属性重命名、json序列化成Map等操作,并展示了如何处理json字符串中的双引号问题。同时,讨论了Gson的配置,如处理空值、日期格式化等。 摘要由CSDN通过智能技术生成

遇到一个场景使用gjson解析无固定模板的json串变成TreeMap时value值出现两个双引号

0.1解决方法

如果直接用 JsonObject.toSring或者jo.get(“name”).toString的话,取出的值会有双引号,直接getAsString就没有双引号啦

1.gson的使用

1.1对象转json

gson的maven

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.8.7</version>
</dependency>

准备封装的对象

package learn.JSON.gsonLearn;
import java.math.BigDecimal;
 * @author WangWenLei
 * @DATE: 2021/6/21
public class Student {
    private String name;
    private int age;
    private char sex;
    private float height;
    private BigDecimal money;
    public Student(String name, int age, char sex, float height, BigDecimal money) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.height = height;
        this.money = money;
// getter/setter
package learn.JSON.gsonLearn;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.math.BigDecimal;
 * @author WangWenLei
 * @DATE: 2021/6/21
public class Main {
    public static void main(String[] args) {
        Student student = new Student("wwl",25,'y',170.2F,BigDecimal.valueOf(20210421));
        // 构建
        GsonBuilder gsonBuilder = new GsonBuilder();
        // 创建Gson对象
        Gson gson = gsonBuilder.create();
        // 序列化
        String s = gson.toJson(student);
        System.out.println(s);

1.2 json转对象

package learn.JSON.gsonLearn;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 * @author WangWenLei
 * @DATE: 2021/6/22
public class JsonToObj {
    public static void main(String[] args) {
        String json = "{\"name\":\"wwl\",\"age\":25," +
                "\"sex\":\"y\",\"height\":170.2,\"money\":20210421}";
        Gson gson = new GsonBuilder().create();
        // 单个class的解析
        Student student = gson.fromJson(json, Student.class);
        System.out.println(student.toString());
        // 简单数组的解析
        String json1 = "[\"Android\",\"Java\",\"PHP\"]";
        String[] strings = gson.fromJson(json1, String[].class);
        Arrays.stream(strings).forEach(item -> System.out.println(item + " "));
        System.out.println();
        //对于Java来说List<String> 和List<User> 这俩个的字节码文件
        // 只一个那就是List.class,这是Java泛型使用时要注意的问题 泛型擦除
        //Gson为我们提供了TypeToken来实现对泛型的支持,所以当我们
        // 希望使用将以上的数据解析为List<String>时需要这样写
        List<String> o = gson.fromJson(json1, new TypeToken<List<String>>() {}.getType());
        o.forEach(item -> System.out.print(item + " "));
        System.out.println();
        // 对于对象
        String jsonArray = "[{\"name\":\"wwl1\",\"age\":25,\"sex\":\"y\"," +
                "\"height\":170.2,\"money\":20210421},{\"name\":\"wwl2\"," +
                "\"age\":25,\"sex\":\"y\",\"height\":170.2,\"money\":20210421}]";
        List<Student> list = gson.fromJson(jsonArray,new TypeToken<List<Student>>(){}.getType());
        System.out.println(list.toString());

1.3属性重命名 @SerializedName 注解的使用

对接不同系统时经常会因为不同的参数命名方法而序列化成不同的名称,在接收时会造成不和谐如:
期望接收json格式:

{"name":"wwl1","age":25,"sex":"y","height":170.2,"money":20210421}

实际接收参数

{"NAME":"wwl1","AGE":25,"SEX":"y","HEIGHT":170.2,"MONEY":20210421}

我们知道Gson在序列化和反序列化时需要使用反射

	@SerializedName("NAME")
	private String name;
	@SerializedName("AGE")
	private int age;
	@SerializedName("SEX")
	private char sex;
	@SerializedName("HEIGHT")
	private float height;
	@SerializedName("MONEY")
	private BigDecimal money;

这样设置后序列化的样子,也得使用这个进行反序列化

{"NAME":"wwl1","AGE":25,"SEX":"y","HEIGHT":170.2,"MONEY":20210421}

2.4版本后 @SerializedName注解除了了value属性还有alternate属性(反序列化时字段的替代名称)接收一个String数组
当上面的三个属性(email_address、email、emailAddress)都中出现任意一个时均可以得到正确的结果。

1.当多种情况同时出时,以最后一个出现的值为准。
2.value值与alternate里的值不能重复

@SerializedName(value = "name",alternate = {"NAME","name1"})
private String name;

name1被反序列化成name

String json = "{\"name1\":\"wwl1\",\"AGE\":25" +
                ",\"SEX\":\"y\",\"HEIGHT\":170.2,\"MONEY\":20210421}";
Gson gson = new GsonBuilder().create();
// 单个class的解析
Student student = gson.fromJson(json, Student.class);
System.out.println(student.toString());

1.4 json序列化成map

先得到一个json串再反序列化成map
结果如下:
在这里插入图片描述
代码如下:

package learn.JSON.gsonLearn;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.Map;
import java.util.TreeMap;
 * @author WangWenLei
 * @DATE: 2021/6/22
public class JsonToMap {
    public static void main(String[] args) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("name","wwl");
        jsonObject.addProperty("age","25");
        jsonObject.addProperty("height","170.2");
        jsonObject.addProperty("data","170.2");
        JsonObject jsonObject1 = new JsonObject();
        jsonObject1.addProperty("key1","value1");
        jsonObject1.addProperty("key2","value2");
        jsonObject.add("data", jsonObject1);
        Gson gson = new GsonBuilder().create();
        String json = gson.toJson(jsonObject);
        System.out.println(json);
        Map<String, Object> o = gson.fromJson(json, new TypeToken<TreeMap<String, Object>>() {}.getType());
        System.out.println(o.toString());
        System.out.println();

2. Gson的配置

// 当字段值为空或null时,依然对该字段进行转换   
.serializeNulls()
// json宽松
.setLenient()
 //对结果进行格式化,增加换行,变得更好看
.setPrettyPrinting()
//时间转化为特定格式
.setDateFormat("yyyy-MM-dd HH:mm:ss:SSS") 
 //不对没有用@Expose注解的属性进行操作
.excludeFieldsWithoutExposeAnnotation()
 //当Map的key为复杂对象时,需要开启该方法
.enableComplexMapKeySerialization()
//防止特殊字符出现乱码。默认是GSON把HTML,转义用的
.disableHtmlEscaping() 
//为某特定对象设置固定的序列或反序列方式,自定义Adapter需实现JsonSerializer或者JsonDeserializer接口
.registerTypeAdapter(Student.class,new StudentAdapter()) 
 

文文的博客~

在使用gsonjson字符串转换成Map<String,Object> 对象时, 我发现原先json字符串中的整形,取出来变成了double类型, 当我取出对应的字段直接toString的时候,再转成Integer时,会抛异常,因为double类型的字符串是不能直接转成整数的。 Gson gson = ne 1、获取json字符串,gson.toJson(entity); 2、通过fromJson方法将json字符串jsonStr转换为type类型,gson.fromJson(jsonStr,type); 在此过程中,gson.toJson(entity)获取到的json字符串如下:"{"name":"张三","age":17}",再转map 结果就成了"nam... &lt;!-- Gson依赖 --&gt; &lt;dependency&gt; &lt;groupId&gt;com.google.code.gson&lt;/groupId&gt; &lt;artifactId&g...
Map的存储结构式Key/Value形式,Key 和 Value可以是普通类型,也可以是自己写的JavaBean(本文),还可以是有泛型的List(下一篇博客).本例中您要重点看如何将Json转回为普通JavaBean对象时TypeToken的定义. public class Point { private int x; private int y; public Po...
项目地址: Github:https://github.com/smileysx/GsonTest Oschina:https://git.oschina.net/ysx_xx/GsonText 详解Gson使用(一)简单对象转化 http://blog.csdn.net/a249900679/article/details/51385913 详解Gson使用(二)泛型
如果所示,json数据内有回车,这时候用Gson解析是会出现错错误的可以进行如下操作(其中content是完整的json数据) 转义回车 转义换行 其他如此类推 还有一个关键的地方,如果jsonvalue值中有”“,也是会出现解析错误的,那么我们可以将”“转变为中文的双引号 将英文引号转为中文的引号方法 private static String jsonString(String s) {
今天是1024节,写篇博客纪念下(其实就是想点亮1024勋章,哈哈哈),想到前段时间做flink的数据采集遇到的json转换数值精度问题导致消费端数据转换异常 逻辑很简单,就是要将一段json格式的报文转成map,随手用了Gson来转换: Map map=gson.fromJson(mapJson,Map.class); 报文中的value值是整型(比如1024),但是转换完就变成...
```java Gson gson = new Gson(); MyObject obj = gson.fromJson(jsonString, MyObject.class); 其中,jsonString 是要转换的 JSON 字符串,MyObject 是要转换成的 Java 对象类型。需要注意的是,MyObject 类必须有与 JSON 字符串中的属性名称相同的属性,并且这些属性必须有对应的 getter 和 setter 方法。 另外,如果 JSON 字符串中包含了数组或嵌套对象,也可以通过 Gson 来进行转换。例如: ```java String jsonArray = "[\"apple\", \"banana\", \"orange\"]"; String jsonObject = "{\"name\": \"John\", \"age\": 30}"; String[] array = gson.fromJson(jsonArray, String[].class); Person person = gson.fromJson(jsonObject, Person.class); 这里的 Person 类是一个自定义的 Java 类型,它包含 name 和 age 两个属性。 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection 26972