我需要以下 DTO
@XmlRootElement(name = "exchangerate")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExchRates {
@XmlJavaTypeAdapter(DateAdapter.class)
private Date date;
@XmlJavaTypeAdapter(JaxbExchangeRatesMapAdapter.class)
private Map<CurrencyUnit, Map<CurrencyUnit, Double>> rates = new HashMap<>();
}
如何将此 xml 解码到上面的 DTO 中?
<exchangerate>
<date>2015-05-04</date>
<EUR>
<EUR>1</EUR>
<GBP>0.73788</GBP>
<USD>1.1152</USD>
</EUR>
<GBP>
<EUR>1.35523</EUR>
<GBP>1</GBP>
<USD>1.51136</USD>
</GBP>
<USD>
<EUR>0.8967</EUR>
<GBP>0.66166</GBP>
<USD>1</USD>
</USD>
</exchangerate>
我阅读了一些教程和示例,但我发现没有一个所有键都是 xml 的节点值。
编辑
几个小时后,我已经接近解决方案了。
我的 XmlAdapter:
public class JaxbExchangeRatesMapAdapter extends XmlAdapter<JaxbExchangeRatesMap, Map<CurrencyUnit, Map<CurrencyUnit, Double>>> {
@Override
public Map<CurrencyUnit, Map<CurrencyUnit, Double>> unmarshal(JaxbExchangeRatesMap v) throws Exception {
return null;
}
@Override
public JaxbExchangeRatesMap marshal(Map<CurrencyUnit, Map<CurrencyUnit, Double>> v) throws Exception {
JaxbExchangeRatesMap map = new JaxbExchangeRatesMap();
for (CurrencyUnit currencyFrom : v.keySet()) {
Map<CurrencyUnit, Double> from = v.get(currencyFrom);
JaxbExchangeRatesEntry entry = new JaxbExchangeRatesEntry();
for (CurrencyUnit currencyTo : from.keySet()) {
entry.getEntries().add(new JAXBElement<>(new QName(currencyTo.getCurrencyCode()), Double.class, from.get(currencyTo)));
}
JAXBElement<JaxbExchangeRatesEntry> jaxbElement = new JAXBElement<>(new QName(currencyFrom.getCurrencyCode()), JaxbExchangeRatesEntry.class, entry);
map.getEntires().add(jaxbElement);
}
return map;
}
}
以及我的映射类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(JaxbExchangeRatesEntry.class)
public class JaxbExchangeRatesMap extends Printable {
private static final long serialVersionUID = 15543456767150881L;
@XmlAnyElement
private List<JAXBElement<JaxbExchangeRatesEntry>> entires = new ArrayList<>();
public List<JAXBElement<JaxbExchangeRatesEntry>> getEntires() {
return entires;
}
public JaxbExchangeRatesMap setEntires(List<JAXBElement<JaxbExchangeRatesEntry>> entires) {
this.entires = entires;
return this;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbExchangeRatesEntry extends Printable {
private static final long serialVersionUID = -694282168028218725L;
@XmlAnyElement
private List<JAXBElement<Double>> entries = new ArrayList<>();
public List<JAXBElement<Double>> getEntries() {
return entries;
}
public JaxbExchangeRatesEntry setEntries(List<JAXBElement<Double>> entries) {
this.entries = entries;
return this;
}
}
这样我得到了以下结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<exchangerate>
<rates>
<USD>
<USD>9.0</USD>
<EUR>7.0</EUR>
<GBP>8.0</GBP>
</USD>
<EUR>
<USD>3.0</USD>
<EUR>1.0</EUR>
<GBP>2.0</GBP>
</EUR>
<GBP>
<USD>6.0</USD>
<EUR>4.0</EUR>
<GBP>5.0</GBP>
</GBP>
</rates>
</exchangerate>
如何删除/跳过费率标签?
最佳答案
我建议您将 XML 构造为:
<exchangerate>
<date>2015-05-04</date>
<currency code="EUR">
<rate code="EUR">1</rate >
<rate code="GBP">0.73788</rate >
<rate code="USD">1.1152</rate >
</currency>
<currency code="GBP">
<rate code="EUR">1.35523</rate >
<rate code="GBP">1</rate >
<rate code="USD">1.51136</rate >
</currency>
<currency code="USD">
<rate code="EUR">0.8967</rate >
<rate code="GBP">0.66166</rate >
<rate code="USD">1</rate >
</currency>
</exchangerate>
并且您有多个类(class):
@XmlAccessorType(XmlAccessType.FIELD)
public class ExchangeRates {
@XmlJavaTypeAdapter(DateAdapter.class)
private Date date;
@XmlElement(name="currency")
private List<Currency> currencies = new ArrayList<>();
....
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Currency {
@XmlAttribute
private String code;
@XmlElement(name="rate")
private List<Rate> rates= new ArrayList<>();
....
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Rate {
@XmlAttribute
private String code;
@XmlValue
private Double value;
....
}
关于java - 使用 Jaxb 解码嵌套 Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45793531/