使用ava關鍵字transient
- private transient int value = 3;
在序列化的時候value不會生成到json字符串中。
使用Gson提供的註解@Expose
- @Exclude
- private String value;
當然,要使用這個屬性必須通過以下語句來構造Gson對象
- new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
我們也可以自定義註解來標註需要過濾的屬性,參見官方的User Guide,需要使用到過濾策略,在下文也會提到。
使用排除策略
以上只能是通過“硬編碼”的方式來排除屬性,有些時候我們需要根據某種來選擇性得過濾一些屬性。這是我們可以使用使用Gson提供的排除策略ExclusionStrategy接口。如:
- public class MyExclusionStrategy implements ExclusionStrategy {
- private MyExclusionStrategy(Class<?> typeToSkip) {
- }
- public boolean shouldSkipClass(Class<?> clazz) {
- return false;
- }
- public boolean shouldSkipField(FieldAttributes f) {
- return false;
- }
- }
我們可以通過類級別和屬性級別來過濾屬性。以上提到的關於自定義註解的實現是在屬性級別上實現的。具體方法是
- public boolean shouldSkipField(FieldAttributes f) {
- // Foo是一個自定義註解
- return f.getAnnotation(Foo.class) != null;
- }
一般情況下,我們可以通過根據屬性名的判斷來實現實現邏輯過濾。當然,在序列化之前,需要用一下代碼來構造Gson對象:
- Gson gson = new GsonBuilder()
- .setExclusionStrategies(new MyExclusionStrategy(SomeObject.class))
- .create();
自定義序列化器
在有些情況下,我們可能會爲某一個類來綁定一種序列化或反序列化器。
- public class MyAdaper1 implements JsonSerializer<DataStore> {
- @Override
- public JsonElement serialize(DataStore src, Type typeOfSrc,
- JsonSerializationContext context) {
- ExclusionStrategy strategy = new DmsExclusionStrategy(
- src.getExcludeFields(), src.getExcludeClasses());
- Gson gson = new GsonBuilder().setExclusionStrategies(strategy)
- .serializeNulls().create();
- return gson.toJsonTree(src);
- }
- }
註冊序列化器:
- GsonBuilder builder = new GsonBuilder();
- builder.registerTypeAdapter(MyType1.class, new MyTypeAdapter())
- .registerTypeAdapter(MyType2.class, new MyTypeAdapter2());
最佳實踐——綜合使用自定義序列化器和排除策略
通常情況下,我們一下如下定義排除策略
- public class DmsExclusionStrategy implements ExclusionStrategy {
- public DmsExclusionStrategy() {
- }
- public DmsExclusionStrategy(String[] excludeFields,
- Class<?>[] excludeClasses) {
- this.excludeFields = excludeFields;
- this.excludeClasses = excludeClasses;
- }
- private String[] excludeFields;
- private Class<?>[] excludeClasses;
- public boolean shouldSkipClass(Class<?> clazz) {
- if (this.excludeClasses == null) {
- return false;
- }
- for (Class<?> excludeClass : excludeClasses) {
- if (excludeClass.getName().equals(clazz.getName())) {
- return true;
- }
- }
- return false;
- }
- public boolean shouldSkipField(FieldAttributes f) {
- if (this.excludeFields == null) {
- return false;
- }
- for (String field : this.excludeFields) {
- if (field.equals(f.getName())) {
- return true;
- }
- }
- return false;
- }
- public final String[] getExcludeFields() {
- return excludeFields;
- }
- public final Class<?>[] getExcludeClasses() {
- return excludeClasses;
- }
- }
定義一個排除模型:
- public class Excludable {
- /**
- * 不需要序列化的域.
- */
- private transient String[] excludeFields;
- /**
- * 不需要序列化的類.
- */
- private transient Class<?>[] excludeClasses;
- public void setExcludeFields(String[] excludeFields) {
- this.excludeFields = excludeFields;
- }
- public String[] getExcludeFields() {
- return excludeFields;
- }
- public void setExcludeClasses(Class<?>[] excludeClasses) {
- this.excludeClasses = excludeClasses;
- }
- public Class<?>[] getExcludeClasses() {
- return excludeClasses;
- }
- }
當我們需要爲某個類應用過濾策略時,我們讓這個類繼承Excludable,自定義其相應的序列化器,在序列化的過程中應用排除策略。
- public class MyTypeSerializer implements JsonSerializer<MyType> {
- @Override
- public JsonElement serialize(MyType src, Type typeOfSrc,
- JsonSerializationContext context) {
- ExclusionStrategy strategy = new DmsExclusionStrategy(
- src.getExcludeFields(), src.getExcludeClasses());
- Gson gson = new GsonBuilder().setExclusionStrategies(strategy)
- .serializeNulls().create();
- return gson.toJsonTree(src);
- }
- }