Jackson 使用循环引用序列化对象

问题描述 投票:0回答:1

使用自定义序列化器时是否可以访问或查找放置在对象上的注释值?


data class Parent(
  val name: String,
  @JsonIgnoreProperties("parent") 
  val child: Child
)
data class Child(
  val name: String,
  val parent: Parent,
)

class CustomSerializer : StdSerializer<Child>(Child::class.java) {
  override fun serialize(obj: Child, gen: JsonGenerator, provider: SerializerProvider) {
     gen.writeStartObject()
     gen.writeFieldName("name")
     gen.writeString(obj.name)
     // if i am serializing a child that is accessed from within a parent object
     // that should not be serialized because of @JsonIgnoreProperties
     // but if I am serializing a Child directly, the parent should be serialized
     gen.writeEndObject()
  }
}
java json kotlin jackson jackson-databind
1个回答
0
投票

我将这段前言添加到我的答案中,以便更好地向阅读这篇文章的人解释您当前的问题。

由于您现在的代码是一个简单的主要内容:

public class Main {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();

        Parent parent = new Parent("parent", null);
        Child child = new Child("child", parent);
        parent.setChild(child);

        System.out.println(mapper.writeValueAsString(parent));
        System.out.println(mapper.writeValueAsString(child));
    }
}

将产生以下输出,重复子对象的编组两次:

{"name":"parent","child":{"name":"child"}}
{"name":"child","parent":{"name":"parent","child":{"name":"child"}}}

在您的情况下,为了防止双重序列化,您不需要诉诸反射来在自定义序列化器中读取字段的注释并决定是否解析该字段,您只需要放置第二个

@JsonIgnoreProperties
注释在您的
parent
课程的
Child
字段之前。

data class Parent(
  val name: String,
  @JsonIgnoreProperties("parent") 
  val child: Child
)

data class Child(
  val name: String,
  @JsonIgnoreProperties("child") 
  val parent: Parent,
)

像这样,参考之前的main,你的输出将是:

{"name":"parent","child":{"name":"child"}}
{"name":"child","parent":{"name":"parent"}}

这里还有 OneCompiler 的现场演示,其中包含可以轻松转换为 Kotlin 的 Java 实现。

© www.soinside.com 2019 - 2024. All rights reserved.