Gson 基本使用 解析、生成、映射
目录
Gson 基本使用 解析、生成、映射
解析和生成
Gson提供了 fromJson()
和 toJson()
两个用于解析和生成的方法,前者实现反序列化,后者实现了序列化。
基本数据类型
Gson gson = new Gson();
int i = gson.fromJson("100", Integer.class); // 100
boolean b = gson.fromJson("true", Boolean.class); // true
String str = gson.fromJson("包青天", String.class); // 包青天
String jsonNumber = gson.toJson(i); // 100
String jsonBoolean = gson.toJson(b); // true
String jsonString = gson.toJson(str); // 包青天
POJO 类
String jsonString = "{\"name\":\"包青天\",\"age\":24}";
User user = gson.fromJson(jsonString, User.class);
User user2 = new User("包青天", 24);
String jsonObject2 = gson.toJson(user2); // {"name":"包青天","age":24}
数组和集合
通过 Gson 解析 jsonArray 时,一般有两种方式:使用数组,或使用 List。
数组比较简单:
String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";
String[] strings = gson.fromJson(jsonArray, String[].class);
String[] strings2 = {"Android", "Java", "PHP"};
String jsonArray2 = gson.toJson(strings2);
但对于 List,将上面的代码中的 String[].class
直接改为 List<String>.class
是行不通的,因为对于 Java 来说,List<String>
和 List<User>
这两个的字节码文件是一个,那就是 List.class
,这是 Java 泛型使用时要注意的问题:泛型擦除
。
为了解决的上面的问题,Gson 为我们提供了 TypeToken
来实现对泛型的支持。
String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";
List<String> list = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
注意:上面的类型是 new TypeToken<List<String>>() {}.getType()
,而不是 new TypeToken<List<String>>().getType()
属性映射
从上面 POJO 的生成与解析可以看出,JSON 串中的 key
和 JavaBean 中的 field
是完全一致的,如果不一致时该怎么办呢?
注解 @SerializedName
Gson 在序列化和反序列化时需要使用反射
,说到反射就不得不想到注解
。一般各类库都将注解放到annotations
包下,打开源码果然有一个annotations
,里面有一个SerializedName
的注解类,这就是我们要找的。
@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 {}; //默认为空
}
映射
通过此注解,便可以将服务端返回的任意 key 的值映射到指定的 field 上,例如:
@SerializedName("email_address")
public String emailAddress;
此注解提供了两个属性,上面用到了其中一个,另外还有一个属性alternate
,接收一个数组,上述案例的完整表达形式为:
@SerializedName(value = "emailAddress", alternate = {"email_address"})
public String emailAddress;
此时,无论 key 是 emailAddress 还是 email_address,都会映射到指定的 field 上。
多键映射
- 当与属性 value 的值或集合 alternate 中任意一个元素的值匹配时,均可正确映射到指定的 field 上
- 当多种情况同时出时,以 json 字符串中
最后一个
出现的值为准
String jsonString = "{\"emailAddress\":\"emailAddress\",\"email_address\":\"email_address\",\"email\":\"email\"}";
System.out.println(new Gson().fromJson(jsonString, User.class).emailAddress);
- 没有指定注解
@SerializedName
时:emailAddress - 指定注解
@SerializedName("email_address")
时:email_address - 指定注解
@SerializedName(value = "emailAddress", alternate = {"email", "email_address"})
时:email - 指定注解
@SerializedName(value = "emailAddress", alternate = {"email_address", "email"})
时:email
2017-09-12
本文来自博客园,作者:白乾涛,转载请注明原文链接:https://www.cnblogs.com/baiqiantao/p/7510028.html