JAXB:如何解组不同类型但具有公共父对象的List?
在我们的应用程序中有一个相当普遍的模式。我们在Xml中配置一组配置对象(或列表)的对象,它们全部实现一个公共接口。在启动时,应用程序读取Xml并使用JAXB创建/配置对象列表。我从来没有想过(多次阅读各种文章之后)仅使用JAXB的“正确方法”。
例如,我们有一个interface
Fee
,以及多个具体的实现类,它们具有一些共同的属性,一些不同的属性以及非常不同的行为。我们用来配置应用程序使用的费用清单的Xml是:
<fees>
<fee type="Commission" name="commission" rate="0.000125" />
<fee type="FINRAPerShare" name="FINRA" rate="0.000119" />
<fee type="SEC" name="SEC" rate="0.0000224" />
<fee type="Route" name="ROUTES">
<routes>
<route>
<name>NYSE</name>
<rates>
<billing code="2" rate="-.0014" normalized="A" />
<billing code="1" rate=".0029" normalized="R" />
</rates>
</route>
</routes>
...
</fee>
</fees>
在上面的Xml中,每个<fee>
元素都对应于Fee接口的具体子类。该type
属性提供有关实例化哪种类型的信息,然后实例化之后,JAXB解组将应用其余Xml中的属性。
我总是不得不做这样的事情:
private void addFees(TradeFeeCalculator calculator) throws Exception {
NodeList feeElements = configDocument.getElementsByTagName("fee");
for (int i = 0; i < feeElements.getLength(); i++) {
Element feeElement = (Element) feeElements.item(i);
TradeFee fee = createFee(feeElement);
calculator.add(fee);
}
}
private TradeFee createFee(Element feeElement) {
try {
String type = feeElement.getAttribute("type");
LOG.info("createFee(): creating TradeFee for type=" + type);
Class<?> clazz = getClassFromType(type);
TradeFee fee = (TradeFee) JAXBConfigurator.createAndConfigure(clazz, feeElement);
return fee;
} catch (Exception e) {
throw new RuntimeException("Trade Fees are misconfigured, xml which caused this=" + XmlUtils.toString(feeElement), e);
}
}
在上面的代码中,JAXBConfigurator
只是用于JAXB对象的简单包装,用于解组:
public static Object createAndConfigure(Class<?> clazz, Node startNode) {
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = context.createUnmarshaller();
@SuppressWarnings("rawtypes")
JAXBElement configElement = unmarshaller.unmarshal(startNode, clazz);
return configElement.getValue();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
最后,在上面的代码中,我们得到一个列表,其中包含在Xml中配置的任何类型。
有没有一种方法可以让JAXB自动执行此操作而不必编写代码来迭代上述元素?
-
注意: 我是 EclipseLink
JAXB(MOXy)的 负责人,并且是
JAXB(JSR-222) 专家组的成员。如果将MOXy用作JAXB提供程序,则可以使用MOXy的
@XmlPaths
注释来扩展标准JAXB@XmlElements
注释,以执行以下操作:费用
import java.util.List; import javax.xml.bind.annotation.*; import org.eclipse.persistence.oxm.annotations.*; @XmlRootElement public class Fees { @XmlElements({ @XmlElement(type=Commission.class), @XmlElement(type=FINRAPerShare.class), @XmlElement(type=SEC.class), @XmlElement(type=Route.class) }) @XmlPaths({ @XmlPath("fee[@type='Commission']"), @XmlPath("fee[@type='FINRAPerShare']"), @XmlPath("fee[@type='SEC']"), @XmlPath("fee[@type='Route']") }) private List<Fee> fees; }
佣金
该
Fee
接口的实现通常会被注释。import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Commission implements Fee { @XmlAttribute private String name; @XmlAttribute private String rate; }
想要查询更多的信息
-
如何解组具有不同值类型的json数组
2021-02-01 关注 0 浏览80 1答案
-
如何解码具有不同类型的JSON属性?
2021-01-31 关注 0 浏览78 1答案
-
如何正确解组不同类型的数组?
2021-02-01 关注 0 浏览91 1答案
-
如何使用泛型类型获取具有相同类型的对象
2021-01-31 关注 0 浏览55 1答案
-
JAXB @XmlElements,类型不同但名称相同?
2021-01-30 关注 0 浏览104 1答案
-
在列表中使用不同类型去解组JSON
2021-02-01 关注 0 浏览148 1答案
-
Java Bean验证:如何指定相同类型但具有不同组的多个验证约束?
2021-01-29 关注 0 浏览122 1答案
-
如何键入提示具有不同类型值的字典
2021-01-29 关注 0 浏览71 1答案
-
不同类型的对象传递
2021-01-29 关注 0 浏览94 1答案
-
排序不同类型对象的高效算法
2021-01-31 关注 0 浏览96 1答案