假设我试图用Jackson序列化以下内容:
public class Investment implements Serializable{
private String shortName;
private MutualFund mutualFund;
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public MutualFund getMutualFund() {
return mutualFund;
}
public void setMutualFund(MutualFund mutualFund) {
this.mutualFund = mutualFund;
}
}
指的是:
public class MutualFund implements Serializable{
private BigDecimal expenseRatio;
private Map<Investment, BigDecimal> underlyingInvestments;
public BigDecimal getExpenseRatio() {
return BigDecimalHelper.guard(expenseRatio);
}
public void setExpenseRatio(BigDecimal expenseRatio) {
this.expenseRatio = expenseRatio;
}
public Map<Investment, BigDecimal> getUnderlyingInvestments() {
return underlyingInvestments;
}
public void setUnderlyingInvestments(Map<Investment, BigDecimal>
underlyingFunds) {
this.underlyingInvestments = underlyingFunds;
}
}
当我尝试将它与Jackson序列化时,其他一切都很好,只是我最终得到了一个Investment对象引用,而不是像我期望的那样带有属性的字符串:
"underlyingInvestments":{"com.financial.detail.Investment@5d465e4b":1}}
我尝试过设计一些自定义序列化器,但没有成功,因为我总是为嵌套的投资获得一个对象引用。所以,我有一个两部分的问题:
- 这个问题可以简单地用Jackson注释来解决吗?
- 如果我必须建立一个自定义序列化器,可以有人善意地指出我在正确的方向上如何最好考虑到这个问题的嵌套性质(例如,一个投资可能包含一个共同基金,而这个共同基金又有一个共同基金的投资…)
问题是您正在使用对象Investment
作为Map的键,所以这里的问题是,您希望json具有哪些键?Json键只能是字符串,所以映射器正在执行Investment
类的toString()
方法。如果您知道该键应该是什么,那么您就可以实现该方法,像这样:
public class Investment implements Serializable {
private String shortName;
private MutualFund mutualFund;
// ...
@Override
public String toString() {
return shortName;
}
}
这将创建一个json对象,像这样:
{
"expenseRatio": 1,
"underlyingInvestments": {
"shortName": 10
}
}
另外,正如@chrylis-谨慎乐观建议的那样,另一个选择是使用@JsonValue
来指示序列化时使用哪个方法,如下所示:
public class Investment implements Serializable{
private String shortName;
private MutualFund mutualFund;
@JsonValue
public String getShortName() {
return shortName;
}
// ...
}