本次的主要内容:
- 字段过滤的几种方法
- 基于
@Expose
注解 - 基于版本
- 基于访问修饰符
- 基于策略(作者最常用)
- 基于
- POJO与JSON的字段映射规则
一、字段过滤的几种方法
字段过滤Gson中比较常用的技巧,特别是在Android中,在处理业务逻辑时可能需要在设置的POJO中加入一些字段,但显然在序列化的过程中是不需要的,并且如果序列化还可能带来一个问题就是 循环引用 ,那么在用Gson序列化之前为不防止这样的事件情发生,你不得不作另外的处理。
以一个商品分类Category
为例。
{
"id": 1,
"name": "电脑",
"children": [
{
"id": 100,
"name": "笔记本"
},
{
"id": 101,
"name": "台式机"
}
]
}
一个大分类,可以有很多小分类,那么显然我们在设计Category
类时Category
本身既可以是大分类,也可以是小分类。
public class Category {
public int id;
public String name;
public List<Category> children;
}
但是为了处理业务,我们还需要在子分类中保存父分类,最终会变成下面的情况
public class Category {
public int id;
public String name;
public List<Category> children;
//因业务需要增加,但并不需要序列化
public Category parent;
}
但是上面的parent
字段是因业务需要增加的,那么在序列化是并不需要,所以在序列化时就必须将其排除,那么在Gson
中如何排除符合条件的字段呢?下面提供4种方法,大家可根据需要自行选择合适的方式。
基于@Expose注解
@Expose提供了两个属性,且都有默认值,开发者可以根据需要设置不同的值。
@Expose 注解从名字上就可以看出是暴露的意思,所以该注解是用于对处暴露字段的。可是我们以前用Gson的时候也没有@Expose 注解还是不正确的序列化为JSON了么?是的,所以该注解在使用new Gson()
时是不会发生作用。毕竟最常用的API要最简单,所以该注解必须和GsonBuilder
配合使用。
使用方法: 简单说来就是需要导出的字段上加上@Expose 注解,不导出的字段不加。注意是不导出的不加。
@Expose //
@Expose(deserialize = true,serialize = true) //序列化和反序列化都都生效
@Expose(deserialize = true,serialize = false) //反序列化时生效
@Expose(deserialize = false,serialize = true) //序列化时生效
@Expose(deserialize = false,serialize = false) // 和不写一样
注:根据上面的图片可以得出,所有值为true
的属性都是可以不写的。
拿上面的例子来说就是
public class Category {
@Expose public int id;
@Expose public String name;
@Expose public List<Category> children;
//不需要序列化,所以不加 @Expose 注解,
//等价于 @Expose(deserialize = false,serialize = false)
public Category parent;
}
在使用Gson时也不能只是简单的new Gson()
了。
Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
gson.toJson(category);
基于版本
Gson在对基于版本的字段导出提供了两个注解 @Since
和 @Until
,和GsonBuilder.setVersion(Double)
配合使用。@Since
和 @Until
都接收一个Double
值。
使用方法:当前版本(GsonBuilder中设置的版本) 大于等于Since的值时该字段导出,小于Until的值时该该字段导出。
class SinceUntilSample {
@Since(4)
public String since;
@Until(5)
public String until;
}
public void sineUtilTest(double version){
SinceUntilSample sinceUntilSample = new SinceUntilSample();
sinceUntilSample.since = "since";
sinceUntilSample.until = "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"}
//当version >=5时,结果:{"since":"since"}
注:当一个字段被同时注解时,需两者同时满足条件。
基于访问修饰符
什么是修饰符? public
、static
、final
、private
、protected
这些就是,所以这种方式也是比较特殊的。
使用方式:
class ModifierSample {
final String finalField = "final";
static String staticField = "static";
public String publicField = "public";
protected String protectedField = "protected";
String defaultField = "default";
private String privateField = "private";
}
使用GsonBuilder.excludeFieldsWithModifiers
构建gson,支持int
形的可变参数,值由java.lang.reflect.Modifier
提供,下面的程序排除了privateField
、 finalField
和staticField
三个字段。
ModifierSample modifierSample = new ModifierSample();
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PRIVATE)
.create();
System.out.println(gson.toJson(modifierSample));
// 结果:{"publicField":"public","protectedField":"protected","defaultField":"default"}
到此为止,Gson提供的所有注解就还有一个@JsonAdapter
没有介绍了,而@JsonAdapter
将和TypeAdapter
将作为该系列第4篇也是最后一篇文章的主要内容。
基于策略(自定义规则)
上面介绍的了3种排除字段的方法,说实话我除了@Expose以外,其它的都是只在Demo用上过,用得最多的就是马上要介绍的自定义规则,好处是功能强大、灵活,缺点是相比其它3种方法稍麻烦一点,但也仅仅只是想对其它3种稍麻烦一点而已。
基于策略是利用Gson提供的ExclusionStrategy
接口,同样需要使用GsonBuilder
,相关API 2个,分别是addSerializationExclusionStrategy
和addDeserializationExclusionStrategy
分别针对序列化和反序化时。这里以序列化为例。
例如:
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);
if (expose != null && expose.deserialize() == false) return true; //按注解排除
return false;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
// 直接排除某个类 ,return true为排除
return (clazz == int.class || clazz == Integer.class);
}
})
.create();
有没有很强大?
二、 POJO与JSON的字段映射规则
之前在你真的会用Gson吗?Gson使用指南(二) 属性重命名时 介绍了@SerializedName
这个注解的使用,本节的内容与上一次差不多的,但既然叫映射规则那么说的自然是有规律的情况。
还是之前User的例子,已经去除所有注解:
User user = new User("怪盗kidou", 24);
user.emailAddress = "ikidou@example.com";
GsonBuilder
提供了FieldNamingStrategy
接口和setFieldNamingPolicy
和setFieldNamingStrategy
两个方法。
默认实现GsonBuilder.setFieldNamingPolicy
方法与Gson提供的另一个枚举类FieldNamingPolicy
配合使用,该枚举类提供了5种实现方式分别为:
IDENTITY | {"emailAddress":"ikidou@example.com"} |
LOWER_CASE_WITH_DASHES | {"email-address":"ikidou@example.com"} |
LOWER_CASE_WITH_UNDERSCORES | {"email_address":"ikidou@example.com"} |
UPPER_CAMEL_CASE | {"EmailAddress":"ikidou@example.com"} |
UPPER_CAMEL_CASE_WITH_SPACES | {"Email Address":"ikidou@example.com"} |
自定义实现GsonBuilder.setFieldNamingStrategy
方法需要与Gson提供的FieldNamingStrategy
接口配合使用,用于实现将POJO的字段与JSON的字段相对应。上面的FieldNamingPolicy
实际上也实现了FieldNamingStrategy
接口,也就是说FieldNamingPolicy
也可以使用setFieldNamingStrategy
方法。
用法:
Gson gson = new GsonBuilder()
.setFieldNamingStrategy(new FieldNamingStrategy() {
@Override
public String translateName(Field f) {
//实现自己的规则
return null;
}
})
.create();
注意: @SerializedName
注解拥有最高优先级,在加有@SerializedName
注解的字段上FieldNamingStrategy
不生效!
相关推荐
3. **类型适配器(Type Adapters)**:Gson允许自定义类型适配器来处理特定类型的序列化和反序列化逻辑,比如日期、自定义类等。 4. **字段忽略**:通过注解`@Expose`可以控制哪些字段被序列化或反序列化。 5. **...
介绍:Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. 压缩包里有以下文件: ...
3. **复杂类型处理**:Gson能够处理各种复杂的Java类型,包括数组、列表、映射、枚举以及自定义对象等。此外,它还支持泛型,可以处理带有类型参数的类。 4. **流式API**:对于大量数据处理,Gson提供了流式API,...
**三、Gson与其他库的比较** 1. **Jackson vs Gson** Jackson是一个功能更全面的库,提供了更多的性能优化和灵活性,如流式API。然而,Gson以其简单易用和良好的兼容性而受到欢迎。 2. **Fastjson vs Gson** ...
总结来说,这三个JSON解析库各有优势。Gson以其强大的类型映射和灵活性深受喜爱;Fastjson凭借其高效的性能和简洁的API赢得了开发者的心;而org.json则因其轻量级和易用性在某些场景下成为不错的选择。在实际项目中...
GSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。 Gson是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个JSON字符串...
3. **类型转换**:Gson能处理复杂的类型,包括数组、集合、泛型等。例如,将List转换为JSON: ```java List<Person> peopleList = new ArrayList(); // 添加Person对象... String jsonList = new Gson().toJson...
json我们在网络请求中经常用到,最近最火的微信小程序开发中... 就会报错,因为对于嵌套类型的json它是解释不出来的,这时就需要用到com.google.gson.Gson.jar了。资源中提供了jar包与代码示例,一句代码解决您的问题。
Gson是Google的一个开源项目,可以将Java对象转换成JSON,也可能将JSON转换成Java对象。 Gson里最重要的对象有2个Gson 和 GsonBuilder Gson有2个最基本的方法 1) toJson() – 转换java 对象到JSON 2) from...
包含以下java源文件: com.google.gson.DefaultDateTypeAdapter.class com.google.gson.ExclusionStrategy.class com.google.gson.FieldAttributes.class com.google.gson.FieldNamingPolicy.class ...
3. **类型适配器**:Gson提供自定义类型适配器,允许用户在序列化和反序列化过程中控制特定类型的转换行为。 4. **复杂类型处理**:Gson可以处理各种复杂的Java类型,包括数组、集合、Map、枚举以及嵌套对象等。 5...
赠送jar包:gson-2.8.0.jar; 赠送原API文档:gson-2.8.0-javadoc.jar; 赠送源代码:gson-2.8.0-sources.jar; 赠送Maven依赖信息文件:gson-2.8.0.pom; 包含翻译后的API文档:gson-2.8.0-javadoc-API文档-中文...
赠送jar包:gson-2.8.6.jar; 赠送原API文档:gson-2.8.6-javadoc.jar; 赠送源代码:gson-2.8.6-sources.jar; 赠送Maven依赖信息文件:gson-2.8.6.pom; 包含翻译后的API文档:gson-2.8.6-javadoc-API文档-中文...
Gson是Google开发的一款Java库,用于在Java对象和JSON数据之间进行映射。这个库使得Java对象可以被转换为JSON格式的字符串,同时也可以将JSON文本解析为等效的Java对象,极大地简化了JSON数据的处理。在服务端开发中...
Gson是Google开发的一款强大的Java库,用于将Java对象转换为JSON格式的字符串,以及将JSON数据解析回等效的Java对象。这个压缩包包含了Gson库的版本2.8.1,它提供了两个主要的组件:`gson-2.8.1.jar`和`gson-2.8.1-...
在Android Studio中,遇到“Program type already present”错误通常是由于项目中存在多个版本或...同时,这也提醒我们在引入第三方库时,应当注意检查它们的依赖项,避免引入不必要的重复库,以减少潜在的冲突问题。
Gson是Google开发的一款Java库,它能够将Java对象转换为...正确引入Gson的jar文件,无论是通过手动添加还是构建工具配置,都是使用Gson库的第一步。通过熟练掌握Gson,你可以提升项目中JSON数据处理的效率和灵活性。
Gson 是 Google 推出的一款 Java 语言编写的 JSON 库,它允许开发者将 Java 对象转换成 JSON 格式的字符串,反之亦然。Gson 库的强大之处在于其灵活性和简洁性,使得 JSON 序列化和反序列化变得更加简单。 首先,让...
在Java开发中,Gson库是Google提供的一款强大的JSON处理工具,它允许我们将Java对象转换为JSON字符串,反之亦然。本示例"GsonDemo"将深入探讨如何使用Gson库来解析JSON数据。JSON(JavaScript Object Notation)是一...
3. **对象转JSON** 要将Java对象转换为JSON字符串,可以使用`Gson`实例的`toJson()`方法: ```java Gson gson = new Gson(); Person person = new Person("张三", 30); String jsonString = gson.toJson(person...