Gson——循环引用的解决方案

Gson本身并不提供循环引用的直接解决方案。我们可以通过以下方式来解决循环引用的问题:

使用ava关键字transient

[java] view plaincopy
private transient int value = 3;    
在序列化的时候value不会生成到json字符串中。

一起jquery,17jquery

使用Gson提供的注解@Expose 一起jquery,17jquery

[java] view plaincopy
@Exclude  
private String value;    
当然,要使用这个属性必须通过以下语句来构造Gson对象

[java] view plaincopy
new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() <span style="color:#FFFFFF;padding: 0px; margin: 0px;">一起jquery,17jquery</span>   
我们也可以自定义注解来标注需要过滤的属性,参见官方的User Guide,需要使用到过滤策略,在下文也会提到。

使用排除策略

以上只能是通过“硬编码”的方式来排除属性,有些时候我们需要根据某种来选择性得过滤一些属性。这是我们可以使用使用Gson提供的排除策略ExclusionStrategy接口。如:

[java] view plaincopy
public class MyExclusionStrategy implements ExclusionStrategy {  
    private MyExclusionStrategy(Class<?> typeToSkip) {  
        
    }  
  
    public boolean shouldSkipClass(Class<?> clazz) {  
      return false;  
    }  
  
    public boolean shouldSkipField(FieldAttributes f) {  
      return false;  
    }  
  } <span style="color:#FFFFFF;padding: 0px; margin: 0px;">一起jquery,17jquery</span>   
我们可以通过类级别和属性级别来过滤属性。以上提到的关于自定义注解的实现是在属性级别上实现的。具体方法是

[java] view plaincopy
public boolean shouldSkipField(FieldAttributes f) {  
      // Foo是一个自定义注解  
      return f.getAnnotation(Foo.class) != null;  
    }    
内容来自17jquery

一般情况下,我们可以通过根据属性名的判断来实现实现逻辑过滤。当然,在序列化之前,需要用一下代码来构造Gson对象:

一起jquery,17jquery

[java] view plaincopy
Gson gson = new GsonBuilder()  
       .setExclusionStrategies(new MyExclusionStrategy(SomeObject.class))  
       .create(); <span style="color:#FFFFFF;padding: 0px; margin: 0px;">一起jquery,17jquery</span>   
自定义序列化器 一起jquery,17jquery

在有些情况下,我们可能会为某一个类来绑定一种序列化或反序列化器。 一起jquery,17jquery

[java] view plaincopy
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);  
    }  
}    
注册序列化器:

[java] view plaincopy
GsonBuilder builder = new GsonBuilder();  
builder.registerTypeAdapter(MyType1.class, new MyTypeAdapter())  
.registerTypeAdapter(MyType2.class, new MyTypeAdapter2());    
最佳实践——综合使用自定义序列化器和排除策略

通常情况下,我们一下如下定义排除策略

[java] view plaincopy
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;  
    }  
} <span style="color:#FFFFFF;padding: 0px; margin: 0px;">内容来自17jquery</span>   
定义一个排除模型:

[java] view plaincopy
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,自定义其相应的序列化器,在序列化的过程中应用排除策略。

[java] view plaincopy
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);  
    }  
} <span style="color:#FFFFFF;padding: 0px; margin: 0px;">一起jquery,17jquery</span>   
<pre name="code" class="html"><a target=_blank href="http://blog.csdn.net/zsx0321/article/details/8546270" target="_blank">原文链接</a>

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值