我想在单个 Money 对象中解析货币和成本元素。
鉴于提供的 XML,您可以通过为发票创建一个值对象并利用 @JsonUnwrapped 将 currency 和 cost 元素解析为单个 Money 对象。
为发票创建一个值对象
如果您不想为发票创建对象,则可以改为将 XmlMapper 配置为忽略未知属性,并将整个响应反序列化为 Money 对象。在我看来,为您的发票创建一个单独的类是一种更简洁的方法。
创建Invoice 对象的目的是封装响应的所有元素。现在您可能只需要currency 和cost,但稍后您可能需要访问breakdown。对象可以这样构造:
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 属性使用@JsonUnwrapped 进行注释。这可以在字段上、构造函数内部或设置器上,它将“解包”Money 对象并在与Invoice 相同的级别上反序列化其成员。像这样构造您的类,以将货币和成本反序列化为单个对象:
public class Money {
private final String currency;
private final Double cost;
@JsonCreator
public Money(@JsonProperty("currency") String currency,
@JsonProperty("cost") Double cost) {
this.currency = currency;
this.cost = cost;
}
public String getCurrency() {
return currency;
}
public Double getCost() {
return cost;
}
}
内部项目仅指定成本并“重复使用”货币代码。
如果可能,将 Money 和“item”模型分开
为两个不同的模型重用Money 对象不如让一个abject 代表每个视图那么理想。例如,currency 和 cost 的 Money 对象,id、description 和 cost 的 Item 对象。如果这在您的项目中可行,我将为“项目”创建一个像这样的对象:
public class Item {
@JacksonXmlProperty(isAttribute = true)
public final String id;
public final String description;
public final Double cost;
@JsonCreator
public Item(@JsonProperty("id") String id,
@JsonProperty("description") String description,
@JsonProperty("cost") Double cost) {
this.id = id;
this.description = description;
this.cost = cost;
}
public String getId() {
return id;
}
public String getDescription() {
return description;
}
public Double getCost() {
return cost;
}
}
将Money 用于“项目”值
如果您无权创建新对象并需要重用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;
}
}