一般使用Gson我们一般会用在序列化toJson()和反序列化fromJson(),一般就那么几个方法,使用比较方便简单。
[b]Gson在基本类型中的使用[/b]
[b]Gson对POJO类的序列化与反序列化[/b]
[b]Gson中使用泛型[/b]
总结一下上边可能是我们最长用到的
1.将对象序列化
2.将jsonString反序列化为对象
3.将reader反序列化为对象
4.将jsonString反序列化为List<对象> Type
5.将reader反序列化为List<对象> Type
[b]底层分析[/b]
//需要将传递过来的对象直接指定可以序列化
//需要传递过来时候将aaa_bbb直接以aaaBbb解析出来
//或者是需要将驼峰格式转化为下划线的格式
//转化过程中是否需要全部转化为小写
//转化中是否需要序列化null
//序列化中时间格式是否需要修改
//是否有序列化内部类
//是否需要生成特别的json,就是说不是直接拿到就是json比如加几个]}等特殊字符
//是否要转意html标签
//是否可以指定的字段不输出
等等。。。
@Expose //使用默认都是false
@Expose(deserialize = true,serialize = true) //序列化和反序列化都都生效
@Expose(deserialize = true,serialize = false) //反序列化时生效
@Expose(deserialize = false,serialize = true) //序列化时生效
大于等于Since的值时该字段导出,小于Until的值时该该字段导出
一个字段用两个注解时候记得要满足两者
@Since 和 @Until
使用setFieldNamingPolicy时候要注意不要使用@SerializedName,不知道为什么在使用自定义的级别没有@SerializedName的级别高。
所以在遇到@SerializedName想要转换时候要注意,这有可能是你找问题的源头。又会骂gson的烂什么的。
Gson序列化和反序列化的都是借助于GsonBuilder.registerTypeAdapter和GsonBuilder.registerTypeHierarchyAdapter得以施展
//自己构建自己需要的Gson
[b]Gson源码查看 [/b]
接管某种类型的序列化JsonSerializer和反序列化JsonDeserializer
[b]Gson在基本类型中的使用[/b]
Gson gson=new Gson();
int i=gson.fromJson("100",int.class);
double d = gson.fromJson("\"99.99\"", double.class); //99.99
boolean b = gson.fromJson("true", boolean.class); // true
String str = gson.fromJson("String", String.class); // String
System.out.println(i+" " +d+" " +b+ " " +str);
//基本数据类型序列化
String jsonNumber = gson.toJson(100); // 100
String jsonBoolean = gson.toJson(false); // false
String jsonString = gson.toJson("String"); //"String"
[b]Gson对POJO类的序列化与反序列化[/b]
public class User{
private String name;
private int age;
private String emailAddress;
@SerializedName(value = "userInfo",alternate = {"user_info","info"})
private String userInfo;
public User(String name, int age, String emailAddress) {
this.name = name;
this.age = age;
this.emailAddress = emailAddress;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getUserInfo() {
return userInfo;
}
public void setUserInfo(String userInfo) {
this.userInfo = userInfo;
}
}
//先序列化
User user=new User("lijian",22,"山西省");
System.out.println(gson.toJson(user)); //{"name":"lijian","age":22,"emailAddress":"山西省"}
//为POJO字段提供备选属性名alternate提供多个值,如果是多个值中有一个就存那一个,如果都有值就按照alternate 中的最后一个定义获得值,
String jsonString = "{\"name\":\"怪盗kidou\",\"age\":24,emailAddress:23453245,user_info:2323,info:lksjdl}";
User user1=gson.fromJson(jsonString,User.class);
System.out.println(user1.getUserInfo());
[b]Gson中使用泛型[/b]
//数组比较简单
String jsonArray = "[aaaa,bbbb,cccc]";
String[] strings = gson.fromJson(jsonArray, String[].class);
//List中泛型只有对应的List.class所以使用list时候注意List的泛型檫除
//这里Gson为我们引入了TypeToken来对泛型的支持
Gson gson = new Gson();
String jsonArray = "[aaa,bbbb,ccc]";
String[] strings = gson.fromJson(jsonArray, String[].class);
List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>(){}.getType());
System.out.println(stringList); //[aaa, bbbb, ccc]
注意:这里使用时候看看是否自己可以封装一个统一的工具,如果每次使用时候都会new一个TypeToken,试试工具中自己可以封装一些东西让工具调用更加简单
总结一下上边可能是我们最长用到的
1.将对象序列化
2.将jsonString反序列化为对象
3.将reader反序列化为对象
4.将jsonString反序列化为List<对象> Type
5.将reader反序列化为List<对象> Type
[b]底层分析[/b]
//这里就是传递的jsonString,可以看见会构建生成StringReader在执行fromJson(Reader json, Class<T> classOfT),可以看得出其实我们上边的5个可以归结为3个,以后在实际中调用最多的可以单独出来处理封装。
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if(json == null) {
return null;
} else {
StringReader reader = new StringReader(json);
Object target = this.fromJson((Reader)reader, (Type)typeOfT);
return target;
}
}
public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
JsonReader jsonReader = this.newJsonReader(json);
Object object = this.fromJson((JsonReader)jsonReader, (Type)classOfT);
assertFullConsumption(object, jsonReader);
return Primitives.wrap(classOfT).cast(object);
}
//需要将传递过来的对象直接指定可以序列化
//需要传递过来时候将aaa_bbb直接以aaaBbb解析出来
//或者是需要将驼峰格式转化为下划线的格式
//转化过程中是否需要全部转化为小写
//转化中是否需要序列化null
//序列化中时间格式是否需要修改
//是否有序列化内部类
//是否需要生成特别的json,就是说不是直接拿到就是json比如加几个]}等特殊字符
//是否要转意html标签
//是否可以指定的字段不输出
等等。。。
//在初始化构造时候就默认构造进Gson中的值
public Gson() {
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY, Collections.emptyMap(), false, false, false, true, false, false, false, LongSerializationPolicy.DEFAULT, Collections.emptyList());
}
//通过GsonBuilder构建修改默认的值
//自己构建自己需要的Gson
Gson gson = new GsonBuilder().
serializeNulls()//序列化null
.generateNonExecutableJson()//生成不能执行的json
.setDateFormat("yyyy-MM-dd") //设置日期时间格式,
//.setDateFormat(DateFormat.DATE_FIELD)
.disableInnerClassSerialization()//禁止序列化内部类
.disableHtmlEscaping()//禁止转移html
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) //驼峰转化为下划线 常用
.excludeFieldsWithModifiers(Modifier.PRIVATE) //指定某些修饰符,比如private等不输出为json
.excludeFieldsWithModifiers() //指定字段不输出或者用@Expose 常用
.create();
@Expose //使用默认都是false
@Expose(deserialize = true,serialize = true) //序列化和反序列化都都生效
@Expose(deserialize = true,serialize = false) //反序列化时生效
@Expose(deserialize = false,serialize = true) //序列化时生效
大于等于Since的值时该字段导出,小于Until的值时该该字段导出
一个字段用两个注解时候记得要满足两者
@Since 和 @Until
使用setFieldNamingPolicy时候要注意不要使用@SerializedName,不知道为什么在使用自定义的级别没有@SerializedName的级别高。
所以在遇到@SerializedName想要转换时候要注意,这有可能是你找问题的源头。又会骂gson的烂什么的。
Gson序列化和反序列化的都是借助于GsonBuilder.registerTypeAdapter和GsonBuilder.registerTypeHierarchyAdapter得以施展
class UserAdapter<T> extends TypeAdapter<T> {
public void write(JsonWriter jsonWriter, T t) throws IOException {
//序列化操作
}
public T read(JsonReader jsonReader) throws IOException {
//反序列化操作
return null;
}
}
class User {
public String name;
public int age;
public String address;
}
//自己构建自己需要的Gson
Gson gson = new GsonBuilder()
//这里需要重新写自己构建的适应
.registerTypeAdapter(User.class,new UserAdapter<User>()) //如果使用了该类将会失去默认的好多东西
.create();
//转化为String
JsonSerializer<Number> numberJsonSerializer = new JsonSerializer<Number>() {
@Override
public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(String.valueOf(src));
}
};
Gson gson = new GsonBuilder()
.registerTypeAdapter(Integer.class, numberJsonSerializer).create();
//这样类型进去就会转化为String
[b]Gson源码查看 [/b]
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
TypeAdapter cached = (TypeAdapter)this.typeTokenCache.get(type == null?NULL_KEY_SURROGATE:type);
if(cached != null) {
return cached;
} else {
Object threadCalls = (Map)this.calls.get();
boolean requiresThreadLocalCleanup = false;
if(threadCalls == null) {
threadCalls = new HashMap();
this.calls.set(threadCalls);
requiresThreadLocalCleanup = true;
}
Gson.FutureTypeAdapter ongoingCall = (Gson.FutureTypeAdapter)((Map)threadCalls).get(type);
if(ongoingCall != null) {
return ongoingCall;
} else {
try {
Gson.FutureTypeAdapter call = new Gson.FutureTypeAdapter();
((Map)threadCalls).put(type, call);
Iterator var7 = this.factories.iterator();
TypeAdapter candidate;
do {
if(!var7.hasNext()) {
throw new IllegalArgumentException("GSON cannot handle " + type);
}
TypeAdapterFactory factory = (TypeAdapterFactory)var7.next();
candidate = factory.create(this, type);//这里工厂构建对应的适配器
} while(candidate == null);
call.setDelegate(candidate);
this.typeTokenCache.put(type, candidate);
TypeAdapter var10 = candidate;
return var10;
} finally {
((Map)threadCalls).remove(type);
if(requiresThreadLocalCleanup) {
this.calls.remove();
}
}
}
}
}
接管某种类型的序列化JsonSerializer和反序列化JsonDeserializer
@JsonAdapter(UserTypeAdapter.class) //加在类上@JsonAdapter 仅支持 TypeAdapter或TypeAdapterFactory
public class User {
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
public String name;
public int age;
}