如何仅序列化 Jackson 的孩子的 ID
Posted
技术标签:
【中文标题】如何仅序列化 Jackson 的孩子的 ID【英文标题】:How to serialize only the ID of a child with Jackson 【发布时间】:2013-07-06 16:57:12 【问题描述】:在使用 Jackson (fasterxml.jackson 2.1.1) 时,是否有一种仅序列化孩子 id 的内置方法?我们想通过 REST 发送一个 Order
,它有一个 Person
引用。但是 person 对象非常复杂,我们可以在服务器端刷新它,所以我们只需要主键。
或者我需要一个自定义序列化器吗?还是我需要@JsonIgnore
所有其他属性?在请求Order
对象时,这会阻止Person
数据被发回吗?我还不确定我是否需要它,但如果可能的话,我想控制它......
【问题讨论】:
这有帮助吗? ***.com/questions/8179986/… 【参考方案1】:有几种方法。第一个是使用@JsonIgnoreProperties
来删除孩子的属性,如下所示:
public class Parent
@JsonIgnoreProperties("name", "description" ) // leave "id" and whatever child has
public Child child; // or use for getter or setter
另一种可能性,如果子对象总是序列化为 id:
public class Child
// use value of this property _instead_ of object
@JsonValue
public int id;
另外一种方法是使用@JsonIdentityInfo
public class Parent
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@JsonIdentityReference(alwaysAsId=true) // otherwise first ref as POJO, others as id
public Child child; // or use for getter or setter
// if using 'PropertyGenerator', need to have id as property -- not the only choice
public int id;
这也适用于序列化,并忽略 id 以外的属性。但是,结果不会被包装为 Object。
【讨论】:
这真的很有用。谢谢。当您使用@JsonIdentityReference(alwaysAsId=true)
时,Jackson 无法将其反序列化,对吧?是否可以通过编写自定义的 Serializer/Deserializer 来实现相同的功能?
正确 -- 如果没有对象 id 可以匹配,Jackson 无法判断;所以通常这个选项对于仅序列化的用例是有意义的(如果需要,其他东西可以将它拼凑在一起)。自定义(反)序列化器可以做任何你想做的事情,所以理论上是的。
@StaxMan 你能告诉我如何使用 '@JsonIdentityReference(alwaysAsId=true' 但我想让 Result 包装在 Object 中而不是作为普通属性。
@Andrew 不太清楚你的意思。如果孩子是List
或 POJO,基本无知并不关心。但是如果你的意思是申请List
内的内容,此时不能这样做;你需要一个包装器对象。
最后一种方法将第一次出现为字符串"id1"
,然后将下一个作为引用*id1
。如何让它始终作为字符串?【参考方案2】:
您可以像这样编写自定义序列化程序:
public class ChildAsIdOnlySerializer extends StdSerializer<Child>
// must have empty constructor
public ChildAsIdOnlySerializer()
this(null);
public ChildAsIdOnlySerializer(Class<Child> t)
super(t);
@Override
public void serialize(Child value, JsonGenerator gen, SerializerProvider provider)
throws IOException
gen.writeString(value.id);
然后通过使用@JsonSerialize
注释字段来使用它:
public class Parent
@JsonSerialize(using = ChildAsIdOnlySerializer.class)
public Child child;
public class Child
public int id;
【讨论】:
【参考方案3】:例如,给定一个具有员工结构的简单公司,结合
@JsonIgnore
@ManyToOne(cascade = CascadeType.REFRESH, CascadeType.DETACH)
@JoinColumn(name = "child_id")
我建议添加以下内容:
@JsonProperty("child_id")
如果没有它,将 child_id 作为属性发送,您将不会在客户端得到任何东西,并且-
@JsonIgnoreProperties
它将提供复制和粘贴从服务器接收到的 Json 并将其发回以进行更新的选项。如果没有它,您将在发回时收到异常,或者您必须从收到的 Json 中删除 child_id 属性。
public class Company
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
private List<Employee> employees;
@JsonIgnoreProperties(value = "company_id",allowGetters = true)
public class Employee
@JsonIgnore
@ManyToOne(cascade = CascadeType.REFRESH, CascadeType.DETACH)
@JoinColumn(name = "company_id")
public Company company
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class,
property="id")
@JsonIdentityReference(alwaysAsId=true)
@JsonProperty("company_id")
public Company getCompany()
return company;
【讨论】:
以上是关于如何仅序列化 Jackson 的孩子的 ID的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jackson 反序列化来自 json 对象的对象数组