GSON依赖

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>

User类

@Data
@AllArgsConstructor
public class User {
private String name;
private Integer age;
private Date birth;
}

最简单的转json

User user = new User("张三", 20, new Date());
System.out.println(new Gson().toJson(user));
// {"name":"张三","age":20,"birth":"Jan 25, 2021 8:55:44 AM"}

如果值有null如何处理

User user = new User("张三", null, new Date());
System.out.println(new Gson().toJson(user));
// {"name":"张三","birth":"Jan 25, 2021 8:55:44 AM"}

默认null值字段不会输出,如果想输出null可以这么做

GsonBuilder gsonBuilder = new GsonBuilder();
System.out.println(gsonBuilder.serializeNulls().create().toJson(user));
// {"name":"张三","age":null,"birth":"Jan 25, 2021 8:57:04 AM"}

如果想输出空字符串有两个办法


  1. 直接给这个值设置为空字符串
  2. 比较麻烦,需要定义两个类

public class StringNullAdapter extends TypeAdapter<String> {
@Override
public String read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
//空的String对象进行赋值
return "";
}
return reader.nextString();
}

@Override
public void write(JsonWriter writer, String value) throws IOException {
if (value == null) {
writer.value("");
return;
}
writer.value(value);
}
}
public class NullStringToEmptyAdapterFactory implements TypeAdapterFactory {

@Override
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<T> rawType = (Class<T>) type.getRawType();
if (rawType != String.class) {
return null;
}
//针对String的处理
return (TypeAdapter<T>) new StringNullAdapter();
}
}

然后使用

Gson gson2 = new GsonBuilder()
.registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory())
.serializeNulls()
.create();
System.out.println(gson2.toJson(user));
// {"name":"","age":20,"birth":"Jan 25, 2021 9:49:10 AM"}

如何只输出部分字段

使用​​@Expose​​注解来标注

@Data
@AllArgsConstructor
public class User {
@Expose
private String name;
private Integer age;
private Date birth;
}

同时使用时设置​​excludeFieldsWithoutExposeAnnotation​​​则只会输出​​name​​字段的值

User user = new User("张三", 20, new Date());
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.excludeFieldsWithoutExposeAnnotation();
System.out.println(gsonBuilder.serializeNulls().create().toJson(user));
// {"name":"张三"}

如何设置别名,比如我们想让name首字母大写

@Data
@AllArgsConstructor
public class User {
@SerializedName("Name")
private String name;
private Integer age;
private Date birth;
}

可以看到输出的时候​​name​​​变成了​​Name​

User user = new User("张三", 20, new Date());
System.out.println(new Gson().toJson(user));
// {"Name":"张三","age":20,"birth":"Jan 25, 2021 8:55:44 AM"}

版本管理

有时候我们希望某个字段在3.1或之前的版本显示,某些字段在3.2之后的版本才显示

@Since标注的在 3.2 版本(含3.1)以后才会输出,@Until标注的只在 3.1 版本(不含3.1)之前才会输出。

@Data
@AllArgsConstructor
public class User {
@Since(3.2)
private String name;
private Integer age;
@Until(3.1)
private Date birth;
}
User user = new User("张三", 20, new Date());
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setVersion(3.0);
System.out.println(gsonBuilder.serializeNulls().create().toJson(user));
// {"age":20,"birth":"Jan 25, 2021 10:13:12 AM"}

// 需要注意的是,@Until是不含3.1的
gsonBuilder.setVersion(3.1);
// {"age":20}

// 而@Since是包含3.2的
gsonBuilder.setVersion(3.2);
// {"name":"张三","age":20}

日期格式化

Gson gson = gsonBuilder.setDateFormat("yyyy-MM-dd hh:mm:ss").create();
System.out.println(gson.toJson(user));
// {"name":"张三","年龄":null,"birth":"2021-01-25 09:09:49"}

忽略某个字段

@Data
@AllArgsConstructor
public class User {
private transient String name;
private Integer age;
private Date birth;
}
Gson gson = gsonBuilder.setDateFormat("yyyy-MM-dd hh:mm:ss").create();
System.out.println(gson.toJson(user));
// {"年龄":null,"birth":"2021-01-25 09:09:49"}

避免Gson使用时将一些字符自动转换为Unicode转义字符

例如:


{“s”:"\u003c"}


我只想简单的打印成这样


{“s”:"<"}


解决方案:

Gson gson = new GsonBuilder().disableHtmlEscaping().create();

防止Gson将整数表示为浮点数

有时候我们的数值类型时1,经过Gson转换后变成了浮点数1.0,需要做如下处理才不会被转换为浮点数。

Gson gson = new GsonBuilder().
registerTypeAdapter(Double.class, new JsonSerializer<Double>() {

@Override
public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
if(src == src.longValue())
return new JsonPrimitive(src.longValue());
return new JsonPrimitive(src);
}
}).create();