Циркулярная ссылка с JSON-B

У меня есть два класса, которые ссылаются друг на друга. Когда я пытаюсь сериализовать классы в Json, я получаю ошибку циклической ссылки. Может кто-нибудь сказать мне, как это исправить?

У меня есть класс папки со списком паролей:

public class Folder {

    private List<Password> items = new ArrayList<>();
    private String name;

    public Folder(String name) {
        this.name = name;
    }

    public void add(Password password) {
        items.add(password);
    }

    public List<Password> getItems() {
        return items;
    }

    public void setItems(List<Password> items) {
        this.items = items;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }       
}

Затем у меня есть класс Password, который ссылается на класс Folder:

public class Password {

    private String name;
    private Folder mFolder;

    public Password(String name, Folder folder) {
        this.name = name;
        folder.add(this);
        mFolder = folder;       
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Folder getmFolder() {
        return mFolder;
    }

    public void setmFolder(Folder mFolder) {
        this.mFolder = mFolder;
    }    
}

и наконец главный класс:

public class Main {

    public static void main(String[] args) throws IOException {

        Password password = new Password("Password", new Folder("Folder"));

        Jsonb jsonb = JsonbBuilder.create();        
        try (Writer writer = new StringWriter()) {          
            jsonb.toJson(password, writer);
            System.out.println(writer.toString());
        }
    }    
}

Получите следующее исключение:

at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
    at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:91)
    at org.eclipse.yasson.internal.serializer.CollectionSerializer.serializeInternal(CollectionSerializer.java:76)
    at org.eclipse.yasson.internal.serializer.CollectionSerializer.serializeInternal(CollectionSerializer.java:35)
    at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
    at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:91)
    at org.eclipse.yasson.internal.serializer.ObjectSerializer.marshallProperty(ObjectSerializer.java:92)
    at org.eclipse.yasson.internal.serializer.ObjectSerializer.serializeInternal(ObjectSerializer.java:59)

2 ответа

Решение

В любом Password или же Folder Вам нужно удалить их ссылки (в сериализации) друг на друга. Ты можешь использовать @JsonbTransient в поле, которое вы не хотите сериализовать в JSON.

(документы: http://json-b.net/docs/user-guide.html)

Пример: Password классовый подход

@JsonbTransient
private Folder mFolder;

Пример: Folder классовый подход

@JsonbTransient
private List<Password> items = new ArrayList<>();

Теперь вам решать, какой класс не будет показывать ссылку на другой класс.

Эта проблема возникает, когда два класса ссылаются друг на друга. ты можешь использовать GSONBuilder чтобы получить пользовательский объект GSON, используя setExclusionStrategies метод

GSON gsonObject = new GsonBuilder()
    .setExclusionStrategies(new ExclusionStrategy() {
     /** boolean method shouldSkipClass(Class<?> clz) */
     /** boolean method shouldSkipField(FieldAttributes field) */
});
Другие вопросы по тегам