1

我有一个数据结构 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 有点混乱,因为目录现在有一些书(缺少原版)。更好的是允许指定对每个字段进行一次序列化。让 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"
    },
  ]
}
4

2 回答 2

1

我最近遇到了一个类似的问题:Jackson - serialization of entity with birectional Relations (avoiding cycles)

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

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...
于 2012-04-20T15:04:02.430 回答
0
  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;

于 2013-05-03T08:16:07.927 回答