Gson 使用总结 高级用法
Gson基本用法
//基本数据类型的解析 int i = gson.fromJson("100", int.class); //100 boolean b = gson.fromJson("true", boolean.class); // true String str = gson.fromJson("包青天", String.class); // 包青天
//基本数据类型的生成
String jsonNumber = gson.toJson(100); // 100
String jsonBoolean = gson.toJson(true); // true
String jsonString = gson.toJson("包青天"); // 包青天
System.out.println(i + " " + b + " " + str + " " + jsonNumber + " " + jsonBoolean + " " + jsonString);//100 true 包青天 100 true "包青天"
class User {
//省略构造函数、toString方法等
public String name;
public int age;
}//生成JSON
User user = new User("包青天",24);
String jsonObject = gson.toJson(user); // {"name":"包青天","age":24}
//解析JSON:
String jsonString = "{"name":"包青天","age":24}";
User user = gson.fromJson(jsonString, User.class);
属性重命名 @SerializedName
期望的json格式:
{"name":"包青天","age":24,"emailAddress":"ikidou@example.com"}
实际的json格式:
{"name":"包青天","age":24,"email_address":"ikidou@example.com"}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD })
public @interface SerializedName {
String value();//方法名为value()的属性不需要指定key
String[] alternate() default {};//默认为空
}
@SerializedName("email_address")
public String emailAddress;
为POJO字段提供备选属性名
{"name":"包青天","age":24,"emailAddress":"ikidou@example.com"}
{"name":"包青天","age":24,"email_address":"ikidou@example.com"}
{"name":"包青天","age":24,"email":"ikidou@example.com"}
@SerializedName(value = "emailAddress", alternate = {"email", "email_address"})
public String emailAddress;
Gson中使用泛型 TypeToken
String jsonArray = "["Android","Java","PHP"]";
String[] strings = gson.fromJson(jsonArray, String[].class);
List<String> list = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
泛型解析对POJO设计的影响
{"code":"0","message":"success","data":{}}
{"code":"0","message":"success","data":[]}
public class UserResponse {
public int code;
public String message;
public User data;
}
public class Result<T> {
public int code;
public String message;
public T data;
}
Gson的流式反序列化 JsonReader
public String toJson(Object src);//序列化,通用
//反序列化,自动方式
public <T> T fromJson(String json, Class<T> classOfT);//普通的对象
public <T> T fromJson(String json, Type typeOfT);//使用泛型时使用
//反序列化,手动方式
public <T> T fromJson(Reader json, Class<T> classOfT);
public <T> T fromJson(Reader json, Type typeOfT);
String json = "{"name":"包青天","age":"24"}";
User user = new User();
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginObject(); // throws IOException
while (reader.hasNext()) {
String s = reader.nextName();
switch (s) {
case "name":
user.name = reader.nextString();
break;
case "age":
user.age = reader.nextInt(); //自动转换
break;
}
}
reader.endObject(); // throws IOException
System.out.println(user.name+" "+user.age); // 包青天 24
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null) return null;
StringReader reader = new StringReader(json);
T target = fromJson(reader, typeOfT);
return target;
}
Gson的流式序列化 JsonWriter
User user = new User("包青天",24);
gson.toJson(user,System.out); // 自动写到控制台
JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));
writer.beginObject() // throws IOException
.name("name").value("包青天")//
.name("age").value(24)//
.name("email").nullValue() //演示null
.endObject(); // throws IOException
writer.close(); // throws IOException。{"name":"包青天","age":24,"email":null}
JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));
writer.beginObject() // throws IOException
.name("name").value("包青天")//
.name("兴趣").beginArray().value("篮球").value("排球").endArray()//
.endObject(); // throws IOException
writer.close(); // throws IOException。{"name":"包青天","兴趣":["篮球","排球"]}
JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));
writer.setIndent(" ");//设置缩进格式,这种格式是Gson默认的、显示效果良好的格式
writer.beginObject()
.name("name").value("包青天")
.name("兴趣")
.beginArray()
.value("篮球").value("足球")
.beginObject().name("数组里的元素不要求是同类型的").value(true).endObject()
.endArray()
.endObject();
writer.close();
{
"name": "包青天",
"兴趣": [
"篮球",
"足球",
{
"数组里的元素不要求是统一类型的": true
}
]
}
使用GsonBuilder配置Gson
Gson gson = new GsonBuilder()
.serializeNulls()//序列化null
.setDateFormat("yyyy-MM-dd") // 设置日期时间格式,另有2个重载方法。在序列化和反序化时均生效
.setPrettyPrinting()//格式化输出。设置后,gson序列号后的字符串为一个格式化的字符串
.create();
User user = new User("包青天", new Date());
System.out.println(gson.toJson(user));
{
"name": "包青天",
"email": null,
"date": "2017-09-12",
}
字段过滤的四种方法
{
"id": 1,
"name": "电脑",
"children": [
{
"id": 100,
"name": "笔记本"
},
{
"id": 101,
"name": "台式机"
}
]
}
public class Category {
public int id;
public String name;
public List<Category> children;
public Category parent; //因业务需要增加,但并不需要序列化
}
基于注解@Expose
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.FIELD})
public @interface Expose{
boolean serialize() default true;//默认序列化生效
boolean deserialize() default true;//默认反序列化生效
}
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();//不配置时注解无效
public class Category {
@Expose public int id;// 等价于 @Expose(deserialize = true, serialize = true)
@Expose public String name;
@Expose public List<Category> children;
public Category parent; //不需要序列化,等价于 @Expose(deserialize = false, serialize = false)
}
基于版本和注解@Since @Until
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.TYPE})
public @interface Since{
double value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.TYPE})
public @interface Until{
double value();
}
class SinceUntilSample {
@Since(4) public String since;//大于等于Since
@Until(5) public String until;//小于Until
@Since(4) @Until(5) public String all;//大于等于Since且小于Until
}Gson gson = new GsonBuilder().setVersion(version).create();
System.out.println(gson.toJson(sinceUntilSample));
//当version <4时,结果:{"until":"until"}
//当version >=4 && version <5时,结果:{"since":"since","until":"until","all":"all"}
//当version >=5时,结果:{"since":"since"}
基于访问修饰符
System.out.println(Modifier.toString(Modifier.fieldModifiers()));//public protected private static final transient volatile
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PRIVATE)//排除了具有private、final或stati修饰符的字段
.create();
基于策略(自定义规则)
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {//返回值决定要不要排除该字段,return true为排除
if ("finalField".equals(f.getName())) return true; //根据字段名排除
Expose expose = f.getAnnotation(Expose.class); //获取Expose注解
if (expose != null && expose.deserialize() == false) return true; //根据Expose注解排除
return false;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {//直接排除某个类 ,return true为排除
return (clazz == int.class || clazz == Integer.class);
}
})
.create();
自定义POJO与JSON的字段映射规则
class User {
String emailAddress;
}
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create();//默认
User user = new User("baiqiantao@sina.com");
System.out.println(gson.toJson(user));
FieldNamingPolicy | 结果 |
IDENTITY 个性/特性/恒等式 | {"emailAddress":"baiqiantao@sina.com"} |
LOWER_CASE_WITH_DASHES 小写+破折号 | {"email-address":"baiqiantao@sina.com"} |
LOWER_CASE_WITH_UNDERSCORES 小写+下划线 | {"email_address":"baiqiantao@sina.com"} |
UPPER_CAMEL_CASE 驼峰式+首字母大写 | {"EmailAddress":"baiqiantao@sina.com"} |
UPPER_CAMEL_CASE_WITH_SPACES 驼峰式+空格 | {"Email Address":"baiqiantao@sina.com"} |
public enum FieldNamingPolicy implements FieldNamingStrategy
Gson gson = new GsonBuilder().setFieldNamingStrategy(new FieldNamingStrategy() {
@Override
public String translateName(Field f) {//实现自己的规则
return null;
}
})
.create();
TypeAdapter 自定义(反)序列化
public abstract class TypeAdapter<T> {
public abstract void write(JsonWriter out, T value) throws IOException;
public abstract T read(JsonReader in) throws IOException;
//其它final方法就不贴出来了,包括toJson、toJsonTree、fromJson、fromJsonTree和nullSafe等方法。
}
TypeAdapter 使用示例1
User user = new User("包青天", 24, "baiqiantao@sina.com";
Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class, new UserTypeAdapter())//为User注册TypeAdapter
.create();
System.out.println(gson.toJson(user));
public class UserTypeAdapter extends TypeAdapter<User> {
@Override
public void write(JsonWriter out, User value) throws IOException {
out.beginObject();
out.name("name").value(value.name);
out.name("age").value(value.age);
out.name("email").value(value.email);
out.endObject();
}@Override public User read(JsonReader in) throws IOException { User user = new User(); in.beginObject(); while (in.hasNext()) { switch (in.nextName()) { case "name": user.name = in.nextString(); break; case "age": user.age = in.nextInt(); break; case "email": case "email_address": case "emailAddress": user.email = in.nextString(); break; } } in.endObject(); return user; }
}
TypeAdapter 使用示例2
Gson gson = new GsonBuilder()
.registerTypeAdapter(Integer.class, new TypeAdapter<Integer>() {//接管【Integer】类型的序列化和反序列化过程
//注意,这里只是接管了Integer类型,并没有接管int类型,要接管int类型需要添加【int.class】
@Override
public void write(JsonWriter out, Integer value) throws IOException {
out.value(String.valueOf(value));
}
@Override
public Integer read(JsonReader in) throws IOException {
try {
return Integer.parseInt(in.nextString());
} catch (NumberFormatException e) {
return -1;//当时Integer时,解析失败时返回-1
}
}
})
.registerTypeAdapter(int.class, new TypeAdapter<Integer>() {//接管【int】类型的序列化和反序列化过程
//泛型只能是引用类型,而不能是基本类型
@Override
public void write(JsonWriter out, Integer value) throws IOException {
out.value(String.valueOf(value));
}
@Override
public Integer read(JsonReader in) throws IOException {
try {
return Integer.parseInt(in.nextString());
} catch (NumberFormatException e) {
return -2;//当时int时,解析失败时返回-2
}
}
})
.create();
int i = gson.fromJson("包青天", Integer.class); //-1
int i2 = gson.fromJson("包青天", int.class); //-2
System.out.println(i + " " + i2);//-1 -2
Json(De)Serializer
Gson gson = new GsonBuilder()
.registerTypeAdapter(Integer.class, new JsonDeserializer<Integer>() {
@Override
public Integer deserialize(JsonElement j, Type t, JsonDeserializationContext c) throws JsonParseException {
try {
return j.getAsInt();
} catch (NumberFormatException e) {
return -1;
}
}
})
.create();
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)
.registerTypeAdapter(Long.class, numberJsonSerializer)
.registerTypeAdapter(Float.class, numberJsonSerializer)
.registerTypeAdapter(Double.class, numberJsonSerializer)
.create();
泛型与继承
Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter (Number.class, numberJsonSerializer)
.create();
registerTypeAdapter | registerTypeHierarchyAdapter | |
---|---|---|
支持泛型 | 是 | 否 |
支持继承 | 否 | 是 |
Type type = new TypeToken<List<User>>() {}.getType();//被序列化的对象带有【泛型】
TypeAdapter<List<User>> typeAdapter = new TypeAdapter<List<User>>() { .../省略实现的方法/ };
Gson gson = new GsonBuilder()
.registerTypeAdapter(type, typeAdapter)//注册了与此type相应的TypeAdapter
.create();
String result = gson.toJson(list, type);//明确指定type时才会使用注册的TypeAdapter托管序列化和反序列化
String result2 = gson.toJson(list);//不指定type时使用系统默认的机制进行序列化和反序列化
TypeAdapterFactory
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getType() == Integer.class || type.getType() == int.class) return intTypeAdapter;
return null;
}
})
.create();
注解 @JsonAdapter
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD})//作用在类或字段上
public @interface JsonAdapter{
Class<?> value();
boolean nullSafe() default true;
}
@JsonAdapter(UserTypeAdapter.class) //加在类上
public class User {
public String name;
public int age;
}