Gson使用
項(xiàng)目地址:https://github.com/google/gson
實(shí)例化Gson對(duì)象
-
通過(guò)構(gòu)造函數(shù)獲取
Gson gson = new Gson();
-
通過(guò)
GsonBuilder
獲取取试,可以進(jìn)行多項(xiàng)配置Gson gson = new GsonBuilder().create();
生成Json字符串
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name","hyf");
jsonObject.addProperty("age",21);
jsonObject.addProperty("Boolean",true);
JsonElement
JsonObject jsonObject = new JsonObject();
Json.addProperty("String", "leavesC");
jsonObject.addProperty("Number", 23);
jsonObject.addProperty("Number", 22.9);
jsonObject.addProperty("Boolean", true);
jsonObject.addProperty("Char", 'c');
JsonObject jsonElement = new JsonObject();
jsonElement.addProperty("Boolean", false);
jsonElement.addProperty("Double", 25.9);
jsonElement.addProperty("Char", 'c');
jsonObject.add("JsonElement", jsonElement);
Json和數(shù)組/List轉(zhuǎn)換
1. json轉(zhuǎn)字符串?dāng)?shù)組
Gson gson = new Gson();
String jsonArray = "[\"3\",\"4\",\"5\"]";
String[] strings = gson.fromJson(jsonArray,String[].class);
2. 字符串?dāng)?shù)組轉(zhuǎn)json
String jsonArray = gson.toJson(jsonArray,new TypeToken<String>(){}.getType());
3. json轉(zhuǎn)List
String jsonArray = "[....]" //此處jsonArray與(1)中相同
List<String> stringList = gson.fromJson(jsonArray,new TypeToken<List<String>>(){}.getType());
4. List轉(zhuǎn)Json
String jsonArray = gson.toJson(stringList,new TypeToken<List<String>>(){}.getType());
序列化和反序列化
1. 序列化
User user = new User("hyf",22,true); //假設(shè)有一個(gè)userBean里面有name,age,gender
Gson gson = new Gson();
String json = gson.toJson(user);
//out: {"name":"hyf","age":22,"gender":true}
2. 反序列化
User user = gson.fromJson(json,User.class);
//此處的json為上面序列化輸出的json字符串
屬性重命名
修改User
類幌甘,為name
聲明SerializedName
龄章。其中value
設(shè)置屬性名,而alternate
則設(shè)置多個(gè)備選屬性名
public class User{
@SerializedName(value = "userName",alternate={"user_name","Name"})
private String name;
private int age;
private boolean gender;
}
字段過(guò)濾
1. 基于@Expose注解
Expose注解的注解值聲明情況有四種
@Expose(serialize=true,deserialize=true)//序列化和反序列化都生效
@Expose(serialize=false,deserialize=false)
//序列化和反序列化都不生效
@Expose(serialize=true,deserialize=false)
//序列化生效碰镜,反序列化不生效
@Expose(serialize=false,deserialize=true)
//序列化不生效,反序列化生效
2. 基于版本
Gson提供了@Since
和@Until
兩個(gè)注解基于版本對(duì)字段進(jìn)行過(guò)濾习瑰,它們都包含一個(gè)Double
值绪颖,用于設(shè)置版本號(hào)。
- @Since 從...開(kāi)始
- @Until 到...為止
- 它們要配合
GsonBuilder
配合使用
當(dāng)版本(GsonBuilder
設(shè)置的版本)大于或等于Since
值或小于Until
時(shí)甜奄,字段會(huì)進(jìn)行序列化和反序列操作柠横,而沒(méi)有聲明注解的字段都會(huì)加入序列化和反序列操作窃款。
例子:修改User類
public class User {
@Since(1.4)
private String a;
@Since(1.6)
private String b;
@Since(1.8)
private String c;
@Until(1.6)
private String d;
@Until(2.0)
private String e;
public User(String a, String b, String c, String d, String e) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
}
@Override
public String toString() {
return "User{" +
"a='" + a + '\'' +
", b='" + b + '\'' +
", c='" + c + '\'' +
", d='" + d + '\'' +
", e='" + e + '\'' +
'}';
}
}
Gson gson = new GsonBuilder().setVersion(1.6).create();
User user = new User("A", "B", "C", "D", "E");
System.out.println();
System.out.println(gson.toJson(user));
String json = "{\"a\":\"A\",\"b\":\"B\",\"c\":\"C\",\"d\":\"D\",\"e\":\"E\"}";
user = gson.fromJson(json, User.class);
System.out.println();
System.out.println(user.toString());
結(jié)果輸出:只會(huì)序列化和反序列化a,b,c
序列化:{"a":"A","b":"B","e":"E"}
反序列化:User{a='A',b='B',c='null',d='null',e='E'}
3.基于訪問(wèn)修飾符
通過(guò)GsonBuilder
對(duì)象的excludeFieldsWithModifiers
方法來(lái)指定不進(jìn)行序列化和反序列話操作的訪問(wèn)修飾符字段
public class ModifierSample {
public String publicField = "public";
protected String protectedField = "protected";
private String privateField = "private";
String defaultField = "default";
final String finalField = "final";
static String staticField = "static";
}
public static void main(String[] args) {
Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PRIVATE, Modifier.STATIC).create();
ModifierSample modifierSample = new ModifierSample();
System.out.println(gson.toJson(modifierSample));
}
輸出:private和static的字段將不會(huì)被序列化和反序列化
4.基于策略
通過(guò)GsonBuilder
的setExclusionStrategies(ExclusionStrategy... strategies)
來(lái)直接排除指定字段名或者指定字段類型不進(jìn)行序列化和反序列化
Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy(){
@Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
//排除指定字段名(這里指定字段名為)
return fieldAttributes.getName().equals("intField");
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
//排除指定字段類型(這里指定dobule類)
return aClass.getName().equals(double.class.getName());
}).create();
setExclusionStrategies 方法在序列化和反序列化時(shí)都會(huì)生效,如果只是想指定其中一種情況下的排除策略或分別指定排除策略牍氛,可以改為使用以下兩個(gè)方法
addSerializationExclusionStrategy(ExclusionStrategy strategy);
- addDeserializationExclusionStrategy(ExclusionStrategy strategy);
個(gè)性化設(shè)置
1. 序列化時(shí)輸出null
Gson gson = new GsonBuilder()
.serializeNulls();
.create();
序列化User類: 假設(shè)user類(null,24,true)
輸出:{"name":null,"age":24,"gender":true}
2.格式化輸出Json
Gson默認(rèn)序列化的json字符串不夠直觀晨继,可以使用GsonBuilder
的setPrettyPrinting
進(jìn)行格式化輸出
Gson gson = new GsonBuilder()
.serializeNulls()
.setPrettyPrinting()
.create();
輸出:
{
"name":null,
"age":24,
"gender":true
}
3.格式化時(shí)間
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")
.create();
TypeAdapter
TypeAdapter是一個(gè)泛型抽象類,用于接管某種類型的序列化和反序列過(guò)程搬俊,包含兩個(gè)抽象方法紊扬,分別用于自定義序列化和反序列化的過(guò)程。
例子:對(duì)應(yīng)還是使用User類(包含name,age,gender)
定義一個(gè)類繼承TypeAdapter
public class UserTypeAdapter extends TypeAdapter<User>{
@Override
public void write(JsonWriter jsonWriter, User user) throws IOException {
//流式序列化成對(duì)象開(kāi)始
jsonWriter.beginObject();
//將Json的Key值都指定為大寫字母開(kāi)頭
jsonWriter.name("Name").value(user.getName());
jsonWriter.name("Age").value(user.getAge());
jsonWriter.name("Gender").value(user.isSex());
//流式序列化結(jié)束
jsonWriter.endObject();
}
@Override
public User read(JsonReader jsonReader) throws IOException {
User user = new User();
//流式反序列化開(kāi)始
jsonReader.beginObject();
while (jsonReader.hasNext()) {
switch (jsonReader.nextName()) {
//首字母大小寫均合法
case "name":
case "Name":
user.setName(jsonReader.nextString());
break;
case "age":
user.setAge(jsonReader.nextInt());
break;
case "gender":
user.setGender(jsonReader.nextBoolean());
break;
}
}
//流式反序列化結(jié)束
jsonReader.endObject();
return user;
}
}
使用:
Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class,new UserTypeAdapter())
.create();
User user = new User("hyf",22,true);
String json = gson.toJson(user);
user = gson.fromJson(json,User.class);
輸出序列化后的json
和反序列化后的user
{"Name":"hyf","Age":22,"Gender":true}
User{name="hyf",age=22,gender=true}
TypeAdapter同時(shí)接管了序列化和反序列化操作
- JsonSerializer 只接管序列化過(guò)程的接口
- JsonDeserializer 只接管反序列化過(guò)程的接口
TypeAdapterFactory
TypeAdapterFactory 是用于創(chuàng)建 TypeAdapter 的工廠類唉擂,通過(guò)參數(shù) TypeToken 來(lái)查找確定對(duì)應(yīng)的 TypeAdapter , 如果沒(méi)有就返回 null 并由 Gson 默認(rèn)的處理方法來(lái)進(jìn)行序列化和反序列化餐屎,否則就由客戶預(yù)定義的 TypeAdapter 來(lái)進(jìn)行處理。
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
//如果 Gson 需要與 User 類相關(guān)的 TypeAdapter 玩祟,則返回我們自己定義的 TypeAdapter 對(duì)象
if (typeToken.getType().getTypeName().equals(User.class.getTypeName())) {
return (TypeAdapter<T>) new UserTypeAdapter();
}
//找不到則返回null
return null;
}
})
.create();