Java “如何序列化/反序列化”;溅起;复杂类型?
我正在连接到外部XMLAPI,并尝试使用JacksonJava “如何序列化/反序列化”;溅起;复杂类型?,java,xml,jackson,Java,Xml,Jackson,我正在连接到外部XMLAPI,并尝试使用JacksonXmlMapper类将其解析为POJO。XML的一部分如下所示: <invoice> <some>element</some> <some_other>element</some_other> <currency>USD</currency> <cost>10.42</cost> <brea
XmlMapper
类将其解析为POJO。XML的一部分如下所示:
<invoice>
<some>element</some>
<some_other>element</some_other>
<currency>USD</currency>
<cost>10.42</cost>
<breakdown>
<item id="1">
<description>blah blah</description>
<cost>4.21</cost>
</item>
</breakdown>
</invoice>
要素
要素
美元
10.42
废话
4.21
我想在一个Money
对象中解析currency
和cost
元素
更糟糕的是,内部的项
s只指定成本并“重用”货币代码。我可以使用Jackson以某种智能的方式解析它们吗
我想在一个Money对象中解析currency和cost元素
给定所提供的XML,您可以通过为发票创建一个值对象并使用它将货币
和成本
元素解析为单个货币
对象
为发票创建值对象
如果不想为发票创建对象,可以将XmlMapper
配置为忽略未知属性,并将整个响应反序列化为Money
对象。在我看来,为发票创建一个单独的类是一种更干净的方法
创建Invoice
对象的目的是封装响应的所有元素。现在您可能只需要货币
和成本
,但稍后您可能需要访问细分
。对象的结构可以如下所示:
public class Invoice {
private final String some;
private final String some_other;
@JsonUnwrapped
private final Money money;
private final List<Item> breakdown;
@JsonCreator
public Invoice(@JsonProperty("some") String some,
@JsonProperty("some_other") String some_other,
@JsonProperty("money") Money money,
@JacksonXmlProperty(localName = "item") List<Item> breakdown) {
this.some = some;
this.some_other = some_other;
this.money = money;
this.breakdown = breakdown;
}
public String getSome() {
return some;
}
public String getSome_other() {
return some_other;
}
public Money getMoney() {
return money;
}
public List<Item> getBreakdown() {
return breakdown;
}
}
内部项目仅指定成本和“重用”货币代码
如果可能,将货币
和“项目”模型分开
对两个不同的模型重用Money
对象不如用一个对象来表示每个视图。例如,Money
对象用于currency
和cost
,而Item
对象用于id
、description
和cost
。如果这在您的项目中是可能的,我会为“item”创建一个类似这样的对象:
重新使用货币
获取“项目”值
如果您无权创建新对象,并且需要重新使用Money
,则可以将XmlMapper
配置为忽略未知属性,并将所有属性放在Money
对象上
配置XmlMapper
忽略未知属性
我建议像这样扩展XmlMapper
:
public class CustomXmlMapper extends XmlMapper {
public CustomXmlMapper() {
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
}
将所有可能的属性添加到Money
当元素存在时,这将填充属性。例如,当“项目”被反序列化时:id
、description
和cost
将被填充,currency
将为空
public class Money {
@JacksonXmlProperty(isAttribute = true)
public final String id;
public final String description;
private final String currency;
private final Double cost;
@JsonCreator
public Money(@JsonProperty("id") String id,
@JsonProperty("description") String description,
@JsonProperty("currency") String currency,
@JsonProperty("cost") Double cost) {
this.id = id;
this.description = description;
this.currency = currency;
this.cost = cost;
}
public String getId() {
return id;
}
public String getDescription() {
return description;
}
public String getCurrency() {
return currency;
}
public Double getCost() {
return cost;
}
}
妙极了!谢谢
public class CustomXmlMapper extends XmlMapper {
public CustomXmlMapper() {
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
}
public class Money {
@JacksonXmlProperty(isAttribute = true)
public final String id;
public final String description;
private final String currency;
private final Double cost;
@JsonCreator
public Money(@JsonProperty("id") String id,
@JsonProperty("description") String description,
@JsonProperty("currency") String currency,
@JsonProperty("cost") Double cost) {
this.id = id;
this.description = description;
this.currency = currency;
this.cost = cost;
}
public String getId() {
return id;
}
public String getDescription() {
return description;
}
public String getCurrency() {
return currency;
}
public Double getCost() {
return cost;
}
}