如何在保留循环引用的同时防止StackOverflowError

如何在保留循环引用的同时防止StackOverflowError

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

问题描述

我有一个循环引用的结构。
为了调试目的,我想转储它。基本上就是任何格式,但我选择了JSON。

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



但是GSON命中循环引用并递归,直到 StackOverflowError



我该如何将GSON限制为




  • 忽略某些类成员?
    不符合 @XmlTransient @JsonIgnore


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


  • 最高2级?




相关:

解决方案

简单地设置字段transient(如 private transient int field = 4; )。 GSON了解这一点。



编辑

无需内置注释; Gson让你插入你自己的战略,排除领域和类。它们不能基于路径或嵌套级别,但注释和名称很好。



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

  class MyExclusionStrategy实现了ExclusionStrategy {

public boolean shouldSkipField(FieldAttributes fa){
String className = fa。 。getDeclaringClass()的getName();
String fieldName = fa.getName();
返回
className.equals(my.model.Person)
&& fieldName.equals( 姓氏);

$ b @Override
public boolean shouldSkipClass(Class<?> type){
//永远不会跳过任何类
return false;


我也可以创建自己的注释:

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

}

然后将 shouldSkipField 方法重写为:

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

这可以让我做这样的事情:

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

// ...

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

$ pre $ g $ gson new GsonBuilder
setsettingStrategies(new MyOwnExclusionStrategy())
.create();


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

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

But GSON hits the circular references and recurses until StackOverflowError.

How can I limit GSON to

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

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

  • go to the depth of at most 2 levels?

Related: Gson.toJson gives StackOverFlowError, how to get proper json in this case? (public static class)

解决方案

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

Edit

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.

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;
    }
}

I could also make my own annotation:

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

}

And rewrite the shouldSkipField method as:

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";

    // ...

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

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

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

08-21 04:11