Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用JSON-B(JSON绑定的Java API)序列化循环引用对象_Java_Json - Fatal编程技术网

如何使用JSON-B(JSON绑定的Java API)序列化循环引用对象

如何使用JSON-B(JSON绑定的Java API)序列化循环引用对象,java,json,Java,Json,我使用JSON-B作为JSON的输出对象,对象中有一个循环引用(请不要要求我删除循环引用),示例代码如下 Person类包含一个属性列表 属性类引用返回形成循环引用的person 在第一次打印中可以输出json,但是在第二次打印语句中,由于触摸对象的循环引用而导致堆栈溢出错误,我不想使用@JsonbTransient忽略其中任何一个,我如何解决这个问题 我希望json输出为 {"id":1,"name":"Jhon","propertyList":[{"person":1, "propertyN

我使用JSON-B作为JSON的输出对象,对象中有一个循环引用(请不要要求我删除循环引用),示例代码如下

Person类包含一个属性列表 属性类引用返回形成循环引用的person

在第一次打印中可以输出json,但是在第二次打印语句中,由于触摸对象的循环引用而导致堆栈溢出错误,我不想使用@JsonbTransient忽略其中任何一个,我如何解决这个问题

我希望json输出为

{"id":1,"name":"Jhon","propertyList":[{"person":1, "propertyName":"Palace"},{"person":1, "propertyName":"Apartment"}]}
示例代码:

import java.util.ArrayList;
import java.util.List;

import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;

public class JsonTest {

    public static void main(String[] args) throws InterruptedException {
        Person person = new Person(1, "Jhon");

        Jsonb jsonb = JsonbBuilder.create();

        //no error as no property is added
        System.out.println("jsonPerson without property: " + jsonb.toJson(person));

        Property p1 = new Property();
        p1.setPropertyName("Palace");
        p1.setPerson(person);

        Property p2 = new Property();
        p2.setPropertyName("Apartment");
        p2.setPerson(person);

        person.getPropertyList().add(p1);
        person.getPropertyList().add(p2);

        /**
         * stackoverflow here
         */
        System.out.println("jsonPerson with property: " + jsonb.toJson(person));
    }


    public static class Property {
        private Person person;
        private String propertyName;
        public Person getPerson() {
            return person;
        }
        public void setPerson(Person person) {
            this.person = person;
        }
        public String getPropertyName() {
            return propertyName;
        }
        public void setPropertyName(String propertyName) {
            this.propertyName = propertyName;
        }
    }

    public static class Person {

        private int id;

        public Person() {
            super();
        }

        public Person(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }

        private String name;

        private List<Property> propertyList = new ArrayList<>();

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

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

        public List<Property> getPropertyList() {
            return propertyList;
        }

        public void setPropertyList(List<Property> propertyList) {
            this.propertyList = propertyList;
        }

    }

}
import java.util.ArrayList;
导入java.util.List;
导入javax.json.bind.Jsonb;
导入javax.json.bind.JsonbBuilder;
公共类JsonTest{
公共静态void main(字符串[]args)引发InterruptedException{
人员=新人员(1,“Jhon”);
jsonbjsonb=JsonbBuilder.create();
//没有错误,因为没有添加属性
System.out.println(“没有属性的jsonPerson:+jsonb.toJson(person));
属性p1=新属性();
p1.setPropertyName(“宫殿”);
p1.一人(人);
属性p2=新属性();
p2.setPropertyName(“公寓”);
p2.一人(人);
person.getPropertyList().add(p1);
person.getPropertyList().add(p2);
/**
*这里堆满了
*/
System.out.println(“具有属性的jsonPerson:+jsonb.toJson(person));
}
公共静态类属性{
私人;
私有字符串propertyName;
公众人物{
返回人;
}
公众人士{
这个人=人;
}
公共字符串getPropertyName(){
返回propertyName;
}
公共void setPropertyName(字符串propertyName){
this.propertyName=propertyName;
}
}
公共静态类人员{
私有int-id;
公众人士(){
超级();
}
公众人物(整数id,字符串名称){
超级();
this.id=id;
this.name=名称;
}
私有字符串名称;
private List propertyList=new ArrayList();
公共int getId(){
返回id;
}
公共无效集合id(内部id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共列表getPropertyList(){
返回属性列表;
}
公共void setPropertyList(列表propertyList){
this.propertyList=propertyList;
}
}
}

最后,我放弃使用JSON-B,而是使用Jackson,使用注释@JsonIdentityInfo这里是我的解决方案:

import java.util.ArrayList;
import java.util.List;

import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonTest {

    private static Person person = null;
    private static List<Property> propertyList = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        person = new Person(1, "Jhon");
        propertyList.add(new Property(1, person, "Palace"));
        propertyList.add(new Property(2, person, "Apartment"));

        person.setPropertyList(propertyList);

        jacksonTest();
        //jsonbTest();
    }

    private static void jacksonTest()
    throws Exception
    {
        String result = new ObjectMapper().writeValueAsString(person);

        System.out.println("result: " + result);
    }

    private static void jsonbTest()
    throws Exception
    {
        Jsonb jsonb = JsonbBuilder.create();
        /**
         * stackoverflow here
         */
        System.out.println("jsonPerson with property: " + jsonb.toJson(person));
    }

    public static class Property extends BaseEntity {
        private Person person;
        private String propertyName;

        public Property(int id, Person person, String propertyName) {
            super();
            setId(id);
            this.person = person;
            this.propertyName = propertyName;
        }

        public Person getPerson() {
            return person;
        }
        public void setPerson(Person person) {
            this.person = person;
        }
        public String getPropertyName() {
            return propertyName;
        }
        public void setPropertyName(String propertyName) {
            this.propertyName = propertyName;
        }
    }

    public static class Person extends BaseEntity {
        public Person() {
            super();
        }

        public Person(int id, String name) {
            super();
            setId(id);
            this.name = name;
        }

        private String name;

        private List<Property> propertyList = new ArrayList<>();

        public String getName() {
            return name;
        }

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

        public List<Property> getPropertyList() {
            return propertyList;
        }

        public void setPropertyList(List<Property> propertyList) {
            this.propertyList = propertyList;
        }

    }

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    public static abstract class BaseEntity {
        private int id;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

    }
}

列表中为什么需要重复的人?如果不设置人员,则此输出将出现…->jsonPerson拥有财产:
{“id”:1,“name”:“Jhon”,“propertyList”:[{“propertyName”:“Palace”},{“propertyName”:“Apartment”}]}
@好奇,因为这是一种双向关系
result: {"id":1,"name":"Jhon","propertyList":[{"id":1,"person":1,"propertyName":"Palace"},{"id":2,"person":1,"propertyName":"Apartment"}]}