@JsonIdentityInfo序列化项



我试图使用@JsonItentityInfo序列化关系以避免循环引用。我创建了一个测试来测试序列化的结果,我发现jackson的行为不像我预期的那样。序列化并不是我想象的那样,事实上,当我试图对序列化的对象进行反序列化时,会抛出异常。我使用的代码是:

public class Test {

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static class A {
private final String id;
private final String name;
private final B b;

public A(final String id, final String name, final B b) {
this.id = id;
this.name = name;
this.b = b;
}

public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
public B getB() {
return this.b;
}
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static class B {
private final String id;
private final String name;

public B(final String id, final String name) {
this.id = id;
this.name = name;
}

public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
}
public static void main(final String[] args) {
try {
System.out.println(
new ObjectMapper().writeValueAsString(new A("1", "a", new B("2", "b"))));
} catch (final JsonProcessingException e) {
e.printStackTrace();
}
}
}

根据我的理解,输出应该是

{"id":"1","name":"a","b":"2"}

但是测试返回

{"id":"1","name":"a","b":{"id":"2","name":"b"}}

实际上,当尝试读取序列化字符串时,jackson会抛出异常。我做错了什么?

谢谢大家的帮助

编辑这个例子不完整。对象应该被包裹在另一个对象中,因此它们两个是序列化的。

package lvillap.deliverytoolsserver.domain;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
private final A a;
private final B b;
public Test(final A a, final B b) {
this.a = a;
this.b = b;
}
public A getA() {
return this.a;
}
public B getB() {
return this.b;
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static class A {
private final String id;
private final String name;
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)
private final B b;
public A(final String id, final String name, final B b) {
this.id = id;
this.name = name;
this.b = b;
}
public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
public B getB() {
return this.b;
}
}
public static class B {
private final String id;
private final String name;
public B(final String id, final String name) {
this.id = id;
this.name = name;
}
public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
}
public static void main(final String[] args) {
try {
final B b = new B("2", "b");
final A a = new A("1", "a", b);
System.out.println(new ObjectMapper().writeValueAsString(new Test(a, b)));
} catch (final JsonProcessingException e) {
e.printStackTrace();
}
}
}

以这种方式实现时,结果是预期的:{"a"{"id"1","name":"a","b":"2";},"b":{"id"2","name":"b"}}

谢谢大家的帮助!

在默认情况下,你会得到你应该得到的。

你能做的就是像下面这样改变你的class A

注意,我已经改变了getB()方法。它不再返回class B的实例。它返回class B实例的id属性。

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static class A {
private final String id;
private final String name;
private final B b;
public A(final String id, final String name, final B b) {
this.id = id;
this.name = name;
this.b = b;
}
public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getB() {
return this.b.id;
}
}

您也可以为class B创建自定义序列化器。

如果你想

{"id":"1","name":"a","b":"2"}
然后将private final B b;更改为private final String b;,删除B类并更改代码
new ObjectMapper().writeValueAsString(new A("1", "a", "2"));

也可以删除@JsonIdentityInfo

我认为一切都是直截了当的,对象Java将被转换为对象json,所以当你在class A中包含class B作为一个字段时,你有嵌套的json对象。

相关内容

  • 没有找到相关文章

最新更新