Appearance
2 人赞同了该文章 Gson介绍 GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串 在使用Gson时需要先引入Gson依赖
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency> Gson 使用 1. 简单对象 序列化/反序列化 序列化:
/** * 简单对象转
Json * * @param obj * @return */publicstaticStringsimpleObjToJson(Objectobj){if(Objects.isNull(obj))return"";try{Gsongson=newGson();returngson.toJson(obj);}catch(Exceptione){e.printStackTrace();}return"";} 测试:
@TestvoidGsonUtilTest(){// 简单对象转
jsonUseruser=newUser(1,"
==张三==
",18);Stringjson=GsonUtil.simpleObjToJson(user);System.out.println(json);} 结果:
{"id":1,"name":" ==张三==
","age":18} 如果对象中存在空值: 先看一下user对象中的数据类型
@Data@AllArgsConstructor@NoArgsConstructorpublicclassUser{privateintid;privateStringname;privateIntegerage;publicUser(Stringname,Integerage){this.name=name;this.age=age;}publicUser(Stringname){this.name=name;}} 测试:
@TestvoidGsonUtilTest(){// 简单对象转
jsonUseruser=newUser("
==张三==
");Stringjson=GsonUtil.simpleObjToJson(user);System.out.println(json);} 结果:
{"id":0,"name":" ==张三==
"} 可以看出基本类型有默认值,包装类不解析 反序列化:
/** * 简单Json转对象
 * * @param json * @param cls * @param <T> * @return */publicstatic<T>TsimpleJsonToObj(Stringjson,Class<T>cls){Gsongson=newGson();if(Objects.isNull(json))returnnull;Tobj=gson.fromJson(json,cls);if(Objects.isNull(obj)){returnnull;}else{returnobj;}} 测试:
@Testvoidtest2(){Stringjson="{"id":1,"name":" ==张三==
","age":18}";Useruser=GsonUtil.simpleJsonToObj(json,User.class);System.out.println(user);} 结果:
User(id=1,name=
==张三==
- ,age=18)
复杂对象 序列化/反序列化(对象中嵌套对象) 同简单对象一样 序列化: 复杂对象:
@Data@AllArgsConstructor@NoArgsConstructorpublicclassUser{privateintid;privateStringname;privateIntegerage;privateJobjob;privateList<String>nickName;publicUser(intid,Stringname,Integerage){this.id=id;this.name=name;this.age=age;}}@DatapublicclassJob{privateStringjobName;privateStringcompany;}/** * 复杂对象转
Json *  * @param obj * @return */publicstaticStringcomplexObjToJson(Objectobj){if(Objects.isNull(obj))return"";try{Gsongson=newGson();returngson.toJson(obj);}catch(Exceptione){e.printStackTrace();}return"";} 测试:
@Testvoidtest3(){Useruser=newUser();user.setId(1);user.setName(" ==张三==
");user.setAge(18);Jobjob=newJob();job.setJobName("Java ==开发==
");job.setCompany(" ==某知名大厂==
");user.setJob(job);List<String>list=Arrays.asList(" ==张三==
","
==法外狂徒==
","
==传奇人物==
");user.setNickName(list);Stringjson=GsonUtil.complexObjToJson(user);System.out.println(json);} 结果:
{"id":1,"name":" ==张三==
","age":18,"job":{"jobName":"Java ==开发==
","company":"
==某知名大厂==
"},"nickName":[" ==张三==
","
==法外狂徒==
","
==传奇人物==
"]} 反序列化:
/** * 复杂Json转对象
 * * @param json * @param cls * @param <T> * @return */publicstatic<T>TcomplexJsonToObj(Stringjson,Class<T>cls){Gsongson=newGson();if(Objects.isNull(json))returnnull;Tobj=gson.fromJson(json,cls);if(Objects.isNull(obj)){returnnull;}else{returnobj;}} 测试:
@Testvoidtest4(){Stringjson="{"id":1,"name":" ==张三==\",\"age\":18,\"job\":{\"jobName\":\"Java==开发==\",\"company\":\"==某知名大厂==\"},\"nickName\":[\"==张三==\",\"==法外狂徒==\",\"==传奇人物==
"]}";Useruser=GsonUtil.complexJsonToObj(json,User.class);System.out.println(user);} 结果:
User(id=1,name=
==张三==
,age=18,job=Job(jobName=Java
==开发==,company===某知名大厂==
),nickName=[
==张三==,==法外狂徒==,==传奇人物==
- ])
数组 序列化/反序列化 这里数据序列化和上面一样, 反序列化又=有一点区别String[] nameArray = gson.fromJson(namesJson, String[].class); 工作中不常用,就不再详细介绍 4. Map和List 序列化反序列化 Map和List是工作中比较常用的,而且这两个操作比较相似:
List序列化和反序列化 序列化:/** * list To Json * * @param list * @return */ public static String listToJson(List list) { if (Objects.isNull(list)) return ""; try { Gson gson = new Gson(); return gson.toJson(list); } catch (Exception e) { e.printStackTrace(); } return ""; } 测试:
@Test void test6() { List<String> list = new ArrayList<>(); list.add("zhangsan"); list.add("lisi"); list.add("wangwu"); String json = GsonUtil.listToJson(list); System.out.println(json); } 结果:
java ["zhangsan","lisi","wangwu"]反序列化: 这里反序列化时需要提供Type,通过Gson提供的TypeToken\<T\>.getType()方法可以定义当前List的
Type /** * json to list *  * @param json * @param cls * @param <T> * @return */ public static <T> T jsonToList(String json,Class<T> cls) { if (Objects.isNull(json)) return null; try { Gson gson = new Gson(); // ==需要注意这里的==
type Type type = new TypeToken<ArrayList<T>>(){}.getType(); return gson.fromJson(json, type); } catch (Exception e) { e.printStackTrace(); } return null; } 测试:
@Test void test7() \{ String json = "[\{\"id\":1,\"name\":\"zhangsan\",\"age\":18\},\{\"id\":2,\"name\":\"sili\",\"age\":28\}]"; System.out.println(GsonUtil.jsonToList(json, User.class)); \}
结果: json [{id=1.0, name=zhangsan, age=18.0}, {id=2.0, name=sili, age=28.0}]
Map序列化和反序列化
和List一样 Gson进阶用法 1. 指定序列化和反序列化 字段名称 这个用法是常用的,尤其在解析第三方接口返回数据时,可以指定字段名称解析 实体类加@SerializedName注解
@Data@AllArgsConstructor@NoArgsConstructorpublicclassUser{privateintid;@SerializedName("login_name")privateStringname;privateIntegerage;privateJobjob;privateList<String>nickName;publicUser(intid,Stringname,Integerage){this.id=id;this.name=name;this.age=age;}} 反序列化测试:
@Testvoidtest8(){Stringjson="{"id":1,"login_name":" ==张三==
","age":18}";Useruser=GsonUtil.complexJsonToObj(json,User.class);System.out.println(user);} 结果:
User(id=1,name=
==张三==
- ,age=18,job=null,nickName=null)
- Gson
解析时会将 login_name 解析出的数据封装到 name 属性中 序列化测试:
@Testvoidtest9(){Useruser=newUser(1," ==张三==
",18);System.out.println(GsonUtil.complexObjToJson(user));} 结果:
{"id":1,"login_name":" ==张三==
","age":18} 实际工作中用到场景: 我们工作中经常会需要调用第三方提供的接口,第三方接口数据有些字段命名不符合我们习惯,不如字段用下滑线而我们习惯驼峰命名,这是便可以用@SerializedName注解,这个注解还有一个属性alternate,@SerializedName(value = "login_name", alternate = "name"),此时这个注解意思是如果Json中是login_name就用login_name的值,如果是name就用name值。 2. 忽略解析某个值 有两种方式可以在解析是忽略某个值
@Expose注解
@Data@AllArgsConstructor@NoArgsConstructorpublic class User { @Expose() private int id; // ==参与序列化==/==反序列化==
 @SerializedName("login_name") @Expose(serialize = false,deserialize = false) private String name; // ==不参与序列化,也不参与反序列化==
 @Expose(serialize = false, deserialize = true) private Integer age; // ==只参与反序列化==
 @Expose(serialize = true, deserialize = false) private Job job; // ==只参与序列化==
  private List<String> nickName; public User(int id, String name, Integer age) { this.id = id; this.name = name; this.age = age; }} 在使用这个注解时,就不能使用之前gson对象了,必须使用下面方式构建gson对象,该对象会排除没有注解的字段。
public static String exposeObjToJson(Object obj) \{ if (Objects.isNull(obj)) return ""; try \{ GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.excludeFieldsWithoutExposeAnnotation(); Gson gson = gsonBuilder.create(); return gson.toJson(obj); \} catch (Exception e) \{ e.printStackTrace(); \} return ""; \} public static \<T\> T exposeJsonToObj(String json, Class\<T\> cls) \{ if (Objects.isNull(json)) return null; try \{ GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.excludeFieldsWithoutExposeAnnotation(); Gson gson = gsonBuilder.create(); return gson.fromJson(json, cls); \} catch (Exception e) \{ e.printStackTrace(); \} return null; \}
transient关键字
使用这个关键字,可以直接让变量不参与序列化/反序列化
@Data@AllArgsConstructor@NoArgsConstructorpublic class User { @Expose() private int id; // ==参与序列化==/==反序列化==
 @SerializedName(value = "login_name",alternate = "name") @Expose(serialize = false,deserialize = false) private String name; // ==不参与序列化,也不参与反序列化==
 @Expose(serialize = false) private Integer age; // ==只参与反序列化==
 @Expose(deserialize = false) private Job job; // ==只参与序列化== private transient List\<String\> nickName; // transient ==关键字==
public User(int id, String name, Integer age) { this.id = id; this.name = name; this.age = age; }} 使用该关键字时,直接用普通new的gson对象即可。 > 来自
<https://zhuanlan.zhihu.com/p/451745696\> > 来自
<https://zhuanlan.zhihu.com/p/451745696\>
