JSON-B的循环引用问题

时间:2019-01-08 07:37:47

标签: java json

我有两个互相引用的类。当我尝试将类序列化为Json时,出现循环引用错误。谁能告诉我如何解决这个问题?

我有一个包含密码列表的Folder类:

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

然后我有一个密码类,它引用了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;
    }    
}

最后是Main类:

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 个答案:

答案 0 :(得分:0)

PasswordFolder中,您需要删除彼此的引用(在序列化中)。您可以对不想在JSON中序列化的字段使用@JsonbTransient

(文档:http://json-b.net/docs/user-guide.html#ignoring-properties

示例:Password类方法

@JsonbTransient
private Folder mFolder;

示例:Folder类方法

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

现在由您决定哪个班级不会显示对另一个班级的引用。

答案 1 :(得分:-1)

当两个类相互引用时,会发生此问题。您可以使用GSONBuilder方法来使用setExclusionStrategies获取自定义gson对象

GSON gsonObject = new GsonBuilder()
    .setExclusionStrategies(new ExclusionStrategy() {
     /** boolean method shouldSkipClass(Class<?> clz) */
     /** boolean method shouldSkipField(FieldAttributes field) */
});