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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2016-09-12 Java 面向对象 继承 多态 重写 覆盖