12

循環参照のある構造があります。デバッグ目的で、ダンプしたいと思います。基本的に任意の形式ですが、JSON を選択しました。

どのクラスでもよいので、JAXB アノテーションを必要としない GSON を選択しました。

しかし、GSON は循環参照にヒットし、 まで再帰しStackOverflowErrorます。

GSONを制限するにはどうすればよいですか

  • 特定のクラス メンバを無視しますか? @XmlTransientとの両方@JsonIgnoreが守られていません。

  • 特定のオブジェクト グラフ パスを無視しますか? たとえば、GSON にシリアライズしないように指示できますrelease.customFields.product

  • 最大で 2 レベルの深さに行きますか?

関連: Gson.toJson は StackOverFlowError を返します。この場合、適切な json を取得するにはどうすればよいですか? (パブリック静的クラス)

4

2 に答える 2

24

単純にフィールドを一時的にします (のようにprivate transient int field = 4;)。GSONはそれを理解しています。

編集

組み込みの注釈は必要ありません。Gson を使用すると、フィールドとクラスを除外するための独自の戦略を組み込むことができます。パスまたはネスト レベルに基づくことはできませんが、注釈と名前は問題ありません。

クラス「my.model.Person」の「lastName」という名前のフィールドをスキップしたい場合は、次のような除外戦略を作成できます。

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

これにより、次のようなことが可能になります。

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

    // ...

カスタム ExclusionStrategy を使用するには、ビルダーを使用して Gson オブジェクトをビルドします。

Gson g = new GsonBuilder()
       .setExclusionStrategies(new MyOwnExclusionStrategy())
       .create();
于 2013-01-23T21:16:40.853 に答える