关于gson:Gson的TypeToken与泛型擦除

原创:扣钉日记(微信公众号ID:codelogs),欢送分享,转载请保留出处。问题在Java的json框架中,Gson是应用得比拟宽泛的一个,其Gson类提供了toJson()与fromJson()办法,别离用来序列化与反序列化。 json序列化用得最多的场景是在调用内部服务接口时,大抵如下: @Data@AllArgsConstructorpublic class Response<T>{ int code; String message; T body;}@Data@AllArgsConstructorpublic class PersonInfo{ long id; String name; int age;}/** * 服务端 */public class Server { public static String getPersonById(Long id){ PersonInfo personInfo = new PersonInfo(1234L, "zhangesan", 18); Response<PersonInfo> response = new Response<>(200, "success", personInfo); //序列化 return new Gson().toJson(response); }}/** * 客户端 */public class Client { public static void getPerson(){ String responseStr = Server.getPersonById(1234L); //反序列化 Response<PersonInfo> response = new Gson().fromJson(responseStr, new TypeToken<Response<PersonInfo>>(){}.getType()); System.out.println(response); }}因为大多数接口设计中,都会有对立的响应码构造,因而大多我的项目都会像下面一样,设计一个通用Response类来对应这种对立响应码构造,是很常见的状况。 ...

September 5, 2022 · 2 min · jiezi

关于gson:java基础序列化反序列化gson基础知识

以下内容来之官网翻译,地址 1.Gson依赖1.1.Gradle/Androiddependencies { implementation 'com.google.code.gson:gson:2.9.0'}1.2.maven<dependencies> <!-- Gson: Java to Json conversion --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.9.0</version> <scope>compile</scope> </dependency></dependencies>1.2.Gson简略实用1.2.1.根底类型// SerializationGson gson = new Gson();gson.toJson(1); // ==> 1gson.toJson("abcd"); // ==> "abcd"gson.toJson(new Long(10)); // ==> 10int[] values = { 1 };gson.toJson(values); // ==> [1]// Deserializationint one = gson.fromJson("1", int.class);Integer one = gson.fromJson("1", Integer.class);Long one = gson.fromJson("1", Long.class);Boolean false = gson.fromJson("false", Boolean.class);String str = gson.fromJson("\"abc\"", String.class);String[] anotherStr = gson.fromJson("[\"abc\"]", String[].class);1.2.2.对象class BagOfPrimitives { private int value1 = 1; private String value2 = "abc"; private transient int value3 = 3; BagOfPrimitives() { // no-args constructor }}// SerializationBagOfPrimitives obj = new BagOfPrimitives();Gson gson = new Gson();String json = gson.toJson(obj); // ==> json is {"value1":1,"value2":"abc"}// DeserializationBagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);// ==> obj2 is just like objNotes 如果对象内存在循环援用,序列化时将导致死循环。 ...

April 9, 2022 · 4 min · jiezi

Gson实战之旅

前言最近因为FastJson最近几年的安全漏洞频发,所以后续的项目准备切换到Gson中,而前面的项目也开始准备逐步切换到Gson。 而本文就是因此而产生,本文将会围绕一系列实际的需求来展示如何使用Gson解决实际开发上遇到的问题。 Gson之旅如同前言所说的,以下的章节都是本人遇到的实际场景后如何使用Gson的记录。 初识GsonGson是一个Google开源出来针在Java对象和JSON数据之间进行相互映射的Java类库。而且使用方式很简单。以maven项目为例,只需要添加以下配置即可使用。 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope></dependency>Java对象转JSON而且Gson的API使用起来也很简单,例如Java对象转成JSON字符串,只需要调用Gson的toJson方法即可,示例如下 Gson gson = new Gson();Student student = new Student();student.setId(1L);student.setName("测试用户");student.setSex(false);System.out.println(gson.toJson(student));输出结果 {"id":1,"name":"测试用户","sex":false}JSON转Java对象而将JSON字符串转成Java对象也很简单,只需要调用Gson的fromJson方法即可,示例如下 Gson gson = new Gson();String jsonStr ="{'id':1,'name':'测试用户','sex':false}";Student student = gson.fromJson(jsonStr,Student.class);输出结果 Student(id=1, name=测试用户, sex=false, birthday=null)这里需要注意以下两点 fromJson方法需要传入的是==JSON格式的字符串==和对应==Java对象的类型==才行。Gson是可以识别使用==单引号==的JSON字符串,而实际上==JSON格式规范里面是需要使用双引号==。演示的Student类源码@Data是lombok框架的注解,可以自动生成对应的getter/setter和toString方法。 @Datapublic class Student implements Serializable { /** * 学生ID */ private Long id; /** * 学生名称 */ private String name; /** * 学生性别 */ private Boolean sex; /** * 出生年月日 */ private Date birthday;}日期格式化于是就开始了Gson的使用,很快我就遇到第一个问题了。使用Gson处理第三方接口传过来的JSON字符串时,可以正确将yyyy-MM-dd HH:mm:ss格式(例如2020-01-30 11:30:00)的值转为对应的Date对象。 ...

June 7, 2020 · 1 min · jiezi

Gson-解析-Json举几个常用的实例

一. 序前几天写了一篇,关于利用 GSON 在 JSON 序列化和反序列化之间,数据容错的文章。最简单的利用 @SerializedName 注解来配置多个不同 JSON Key 值,或者再使用 @Expose 来配置一些例外的情况。更复杂一些的数据,可以使用 TypeAdapter 来解决,TypeAdapter 可以说是一颗 GSON 解析 JSON 的银弹,所有复杂数据解析以及容错问题,都可以通过它来解决。还不了解的可以先看看之前的文章《利用 Gson 做好 JSON 数据容错》。 文章评论里和公众号后台有一些小伙伴,针对具体数据容错的场景,提出了具体的问题。今天就在这篇文章里统一解答,并且给出解决方案。 二. GSON 数据容错实例就像前文中介绍的一样,GSON 已经提供了一些简单的注解,去做数据的容错处理。更复杂的操作,就需要用到 TypeAdapter 了,需要注意的是,一旦上了 TypeAdapter 之后,注解的配置就会失效。 2.1 什么是 TypeAdapterTypeAdapter 是 GSON 2.1 版本开始支持的一个抽象类,用于接管某些类型的序列化和反序列化。TypeAdapter 最重要的两个方法就是 write() 和 read() ,它们分别接管了序列化和反序列化的具体过程。 如果想单独接管序列化或反序列化的某一个过程,可以使用 JsonSerializer 和 JsonDeserializer 这两个接口,它们组合起来的效果和 TypeAdapter 类似,但是其内部实现是不同的。 简单来说,TypeAdapter 是支持流的,所以它比较省内存,但是使用起来有些不方便。而 JsonSerializer 和 JsonDeserializer 是将数据都读到内存中再进行操作,会比 TypeAdapter 更费内存,但是 API 使用起来更清晰一些。 虽然 TypeAdapter 更省内存,但是通常我们业务接口所使用的那点数据量,所占用的内存其实影响不大,可以忽略不计。 因为 TypeAdapter、JsonSerializer 以及 JsonDeserializer 都需要配合 GsonBuilder.registerTypeAdapter() 方法,所以在本文中,此种接管方式,统称为 TypeAdapter 接管。 ...

June 25, 2019 · 3 min · jiezi

Gson与ListT对象间的相亲之旅

随着人们的生活水平的提高,连带着人与人之间的相亲渠道也进一步改善。最近偶尔看到几档相亲的综艺节目,不管是平民还是明星。可见相亲的热潮正扑面而来。这不Google与Java两个老家伙也坐不住了,分别想着自己排行285的儿子Gson与自己排行570的女儿List<T>也该到了相亲的年龄了。于是Google与Java两个老油条会心一笑,一起策划了今天的这次相亲之旅。 地下恋情Google回到家就将此事告诉了Gson,通知他明天就去Android Studio匆匆那年餐厅见面。Gson欲言欲止,好像另有隐情,但在父亲高大身躯与凌厉的眼神下答应了下来,而且父亲能够在这众多的儿子中想到自己,也不忍心拒绝父亲的善意。 Gson回到房,躺着床上,脑海回想起自己与Java排行520的女儿Object的地下恋情。 Gson与Object的第一次见面还是被它的Json字符串装扮所吸引。那一天她宛如一朵含苞待放的牡丹花,美而不妖,艳而不俗,千娇百媚,无与伦比。(以上均为Gson视角,请勿迷恋。以下为code视角) { "marquee": { "content": "翠绿烟纱散花裙", "status": true }}这一下就激起了Gson的欲望,而且Gson还有点小得意,对于这种女孩他已经有自己的一套完整攻略方案。既然知道了它的Json字符串格式,就可以迅速创建出它对应的java类 public class HomeMarqueeModel { private MarqueeModel marquee; public static class MarqueeModel { private String content; private boolean status; public String getContent() { return content; } public boolean isStatus() { return status; } } public MarqueeModel getMarquee() { return marquee; }}然后再根据API攻略法则第3089条,使用fromJson方案进行攻略,成功率高达100% HomeMarqueeModel model = new Gson().fromJson(jsonStr, HomeMarqueeModel.class);就这样Gson完成了对Object的第一次攻略,获取到了Object的好感。但Gson不满足,为了完全让Object对自己死心塌地,必须应对Object的所有Json字符串格式。 回去之后,Gson在Android Studio微信平台与Java中的好哥们泛型T打探Object的特性。经过交流,发现T它刚好是这方面的能手,T告诉Gson每一个Object都有它独用的Class属性,为了代表所有的Class类型,刚好可以使用它的泛型T来表示,于是就有了Class<T>。 第二天,Gson主动出击邀请Object去Android Studio匆匆那年餐厅吃饭。Gson还是使用它的fromJson方法,只是在这方法上加入了T的思想。 public <T> T getObjectGirl(String jsonStr, Class<T> tGirl) { T girl = getGson().fromJson(jsonStr, tGirl); return girl; }就这样,Gson完成对Object的所有类型的攻略,从此不再为女友而发愁。回想结束,拉回到现实,对于明天的相亲,Gson打算先用之前的方法试一下,毕竟Gson经过前面的成功实例,还是有点小膨胀, ...

May 10, 2019 · 2 min · jiezi