【问题标题】:Best way to serialize bidir circular references into JSON将 bidir 循环引用序列化为 JSON 的最佳方法
【发布时间】:2012-04-30 02:23:15
【问题描述】:

我有一个数据结构 BookCollection,其中包含一组书籍。每本书都有对其所在的 BookCollection 的引用。这是标准的一对多关系。它在服务器端运行良好,但随后我必须将其发送到客户端。该应用程序使用 Jackson ObjectMapper 进行序列化,设置为 Spring Bean。问题是你不能简单地序列化 BookCollection 和 Books,因为标准 JSON 中没有引用(我确实需要标准 JSON)。

当前的解决方案是将@JsonIgnore 放在Book.collection 字段上,或者更高级,将@JsonManagedReference 放在BookCollection.books 上,将@JsonBackReference 放在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”也有对集合对象的引用,但它没有被序列化,因为它已经被序列化了。此外,集合对象不包括“JSON 简介”一书,因为它已经被序列化了。

当我要求 BookCollection 时,我得到了:

{
  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 有点令人困惑,因为目录现在有一些书籍(缺少原版)。更好的是允许指定将每个 field 序列化一次。让 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"
    },
  ]
}

【问题讨论】:

    标签: json serialization spring-mvc orm jackson


    【解决方案1】:

    我最近遇到了类似的问题:Jackson - serialization of entities with birectional relationships (avoiding cycles)

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

    @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                      property = "@id")
    public class SomeEntityClass ...
    

    【讨论】:

      【解决方案2】:
        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();
                  }
              }
      
          }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-01
        • 2022-07-08
        • 1970-01-01
        • 2016-09-13
        • 2018-08-20
        • 1970-01-01
        • 2017-02-05
        • 1970-01-01
        相关资源
        最近更新 更多