GSON:如何在保持循环引用的同时防止 StackOverflowError? [英] GSON: how to prevent StackOverflowError while keeping circular references?

查看:33
本文介绍了GSON:如何在保持循环引用的同时防止 StackOverflowError?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有循环引用的结构.出于调试目的,我想转储它.基本上和任何格式一样,但我选择了 JSON.

I have a structure with circular references. And for debug purposes, I want to dump it. Basically as any format, but I chose JSON.

因为可以是任何类,所以我选择了不需要JAXB注解的GSON.

Since it can be any class, I chose GSON which doesn't needs JAXB annotations.

但 GSON 遇到循环引用并递归,直到 StackOverflowError.

But GSON hits the circular references and recurses until StackOverflowError.

如何将 GSON 限制为

How can I limit GSON to

  • 忽略某些班级成员?@XmlTransient@JsonIgnore 都没有被遵守.

  • ignore certain class members? Both @XmlTransient and @JsonIgnore are not obeyed.

忽略某些对象图路径?例如.我可以指示 GSON 不要序列化 ​​release.customFields.product.

ignore certain object graph paths? E.g. I could instruct GSON not to serialize release.customFields.product.

最多去2层的深度?

相关:Gson.toJson 给出 StackOverFlowError,在这种情况下如何获得正确的 json?(公共静态类)

推荐答案

简单地使字段成为瞬态(如private瞬态 int field = 4;).GSON 明白这一点.

Simply make the fields transient (as in private transient int field = 4;). GSON understands that.

编辑

无需内置注解;Gson 允许您插入自己的排除字段和类的策略.它们不能基于路径或嵌套级别,但注释和名称很好.

No need for a built-in annotation; Gson lets you plug in your own strategies for excluding fields and classes. They cannot be based on a path or nesting level, but annotations and names are fine.

如果我想跳过类my.model.Person"上名为lastName"的字段,我可以编写这样的排除策略:

If I wanted to skip fields that are named "lastName" on class "my.model.Person", I could write an exclusion strategy like this:

class MyExclusionStrategy implements ExclusionStrategy {

    public boolean shouldSkipField(FieldAttributes fa) {                
        String className = fa.getDeclaringClass().getName();
        String fieldName = fa.getName();
        return 
            className.equals("my.model.Person")
                && fieldName.equals("lastName");
    }

    @Override
    public boolean shouldSkipClass(Class<?> type) {
        // never skips any class
        return false;
    }
}

我也可以自己做注释:

@Retention(RetentionPolicy.RUNTIME)
public @interface GsonRepellent {

}

并将 shouldSkipField 方法重写为:

public boolean shouldSkipField(FieldAttributes fa) {
    return fa.getAnnotation(GsonRepellent.class) != null;
}

这将使我能够执行以下操作:

This would enable me to do things like:

public class Person {
    @GsonRepellent
    private String lastName = "Troscianko";

    // ...

要使用自定义 ExclusionStrategy,请使用构建器构建 Gson 对象:

To use a custom ExclusionStrategy, build Gson object using the builder:

Gson g = new GsonBuilder()
       .setExclusionStrategies(new MyOwnExclusionStrategy())
       .create();

这篇关于GSON:如何在保持循环引用的同时防止 StackOverflowError?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆