当前位置: 首页 > 知识库问答 >
问题:

将bidir循环引用序列化为JSON的最佳方法

屠兴旺
2023-03-14

我有一个数据结构藏书集,里面有一套书。每本书都有它所在藏书的参考文献。这是一种标准的一对多关系。它在服务器端工作得很好,但是我必须把它发送到客户端。该应用程序使用Jackson ObjectMapper进行序列化,设置为Spring Bean。问题是,您不能简单地序列化一个图书集合和书籍,因为标准JSON中没有引用(我确实需要标准JSON)。

当前的解决方案是把@JsonIgnore放在Book.collection字段上,或者更高级的,@JsonManagedResources放在BookCollection.books和@JsonBackResources放在Book.collection.但是这并不能解决我所有的问题,有些请求要求一个Book对象,并且还想得到它的BookCollection。

最终,我正在寻找某种方法来告诉序列化器只包含每个对象一次。因此,当我得到一本书时,JSON看起来像这样:

{
  isbn: 125412416,
  title: "Introduction to JSON",
  collection: {
     name: "Programming Books",
     books: [
         {
             isbn: 18723425,
             title: "Java for experts"
         },
         {
             isbn: 82472347,
             title: "C# and its extensions"
         },
     ]
  }
}

虽然“C#及其扩展”和“Java for experts”也有对collection对象的引用,但它没有序列化,因为它已经序列化了。此外,collection对象不包括“JSON简介”一书,因为它已经序列化。

当我要求藏书时,我得到了:

{
  name: "Programming Book",
  books: [
    {
      isbn: 125412416,
      title: "Introduction to JSON"
    },
    {
      isbn: 18723425,
      title: "Java for experts"
    },
    {
      isbn: 82472347,
      title: "C# and its extensions"
    },
  ]
}

虽然BookCollection序列化非常出色,但Book有点混乱,因为曲库现在有一些书(缺少原始书籍)。更好的是允许指定每个字段序列化一次。让Book.collection被允许序列化一次

将一本书连载如下:

{
  isbn: 125412416,
  title: "Introduction to JSON",
  collection: {
     name: "Programming Books",
     books: [
         {
             isbn: 18723425,
             title: "Java for experts"
         },
         {
             isbn: 82472347,
             title: "C# and its extensions"
         },
         {
             isbn: 125412416,
             title: "Introduction to JSON"
         }
     ]
  }
}

将藏书连载与此类似:

{
  name: "Programming Book",
  books: [
    {
      isbn: 125412416,
      title: "Introduction to JSON"
    },
    {
      isbn: 18723425,
      title: "Java for experts"
    },
    {
      isbn: 82472347,
      title: "C# and its extensions"
    },
  ]
}

共有2个答案

计阳泽
2023-03-14
  namespace ConsoleApplication4
    {
        public class Teacher
        {
            public int MyProperty { get; set; }
            // [ScriptIgnore]
            public ClassRoom working { get; set; }
        }
        public class ClassRoom
        {
            public ClassRoom()
            {

            }
            public int sss { get; set; }
            public int s2 { get; set; }
            public int ddy { get; set; }
            //  [ScriptIgnore]
            public Teacher teachers { get; set; }

        }
        class Program
        {
            static void Main(string[] args)
            {  
                Console.ForegroundColor = ConsoleColor.Green;

                ClassRoom @new = new ClassRoom();
                Teacher @teacher = new Teacher();
                @new.teachers = teacher;
                @teacher.working = @new;

                JavaScriptSerializer serializer = new JavaScriptSerializer();

                List<  ClassRoom> classrooms = new List<ClassRoom>();
                classrooms.Add(@new);
                classrooms.Add(@new);
                classrooms.Add(@new);
                classrooms.Add(@new);
                classrooms.Add(@new);

                var result = (from n in classrooms
                              select n).ToList();//tolist() to convert IEnumrable to list can be modified

                for (int i = 0; i < result.Count; i++)
                {
                    result[i].teachers.working = null;//making all child's parents =null to prevent circular refrencing
                }


                Console.WriteLine(serializer.Serialize(result));

                 Console.ReadLine();
            }
        }

    }

我认为这个解决方案可以解决你的问题,它解决了我的问题(result[I].teachers.working=null;)使导致循环引用的属性=null;

纪晨
2023-03-14

我最近遇到了一个类似的问题:Jackson——具有双向关系的实体序列化(避免循环)

因此,解决方案是升级到Jackson 2.0,并在类中添加以下注释:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...
 类似资料:
  • 问题内容: 我有一组linq到sql类,并使用.NET JavaScriptSerializer将它们序列化为JSON。 但是,一旦我将记录添加到相关表上,序列化就会引发“循环引用异常”。啊! 在这里详细描述。 我有几种选择 将linq to sql类转换为没有关系的类,从而避免循环引用 通过取消关联来剪断循环引用-我不认为这是一个真实的选择 使用ScriptIgnoreAttribute(以某种

  • 问题内容: 有岗位这里,询问如何通过返回EF4CTP5序列化对象时,解决循环引用错误。不久前,我在WCF Web表单项目中遇到了同样的问题。 我能够在WCF / Web窗体项目和MVC3项目中“解决”此问题。我认为什么类型的项目都不重要,因为这似乎是EF序列化的“事物”。 我通过在ObjectContext构造函数中禁用ProxyCreation来解决此问题,如下所示: 我的问题是:有人可以解释为

  • 问题内容: 我需要为某些对象实现JSON序列化,并且在与通用集合进行集成时遇到了一个问题。 所有可序列化的类都实现此接口(JSONObject来自此库): 我基于java.util.list的集合的代码大致如下所示: 我的问题是:当我从JSONObject加载AwesomeList时,我需要创建其元素,但是这是不可能的,因为Java禁止我写 我应该如何修改此任务的方法? 问题答案: 您是否绑定到该

  • 这是一个特定的问题,我在Gson的javadoc中找不到关于这个话题的任何信息。 目前,我正在尝试将Json(1)解析为对象。通常我会将这些值映射到对象,并带有和字段,但是我希望更独立于API。 为了(1)我会 但是如果我们测试另一个endpoint,得到的Json(2)会是这样的 这使得我以前构造的毫无用处,我需要创建一个新的Class,其中包含相应的字段。 所以我真正的问题是: > 是否有一个

  • 问题内容: 上课: 和控制器代码: 它适用于LOCALHOST,但不适用于实时服务器: 错误: Json序列化类型的对象时检测到循环引用 我进行了搜索并找到了属性,因此将模型更改为 但是在实时服务器(win2008)上也会发生相同的错误。 如何避免该错误并成功序列化父数据? 问题答案: 尝试以下代码: …或者如果您仅需要父属性: 它并不是解决问题的真正方法,但在序列化DTO时是一种常见的解决方法。

  • 问题内容: 所以这是我的交易 楷模 ....以下模型(这些模型已连接到EfDbContext)已连接到以下存储库… 接口/存储库 在我的HomeController()中,我得到了一个JsonResult方法,我想返回上下文。这是方法 杰森请求 我收到以下错误: 序列化类型为’System.Data.Entity.DynamicProxies.News_96C0B16EC4AC46070505EE