在我们的应用程序中有一个相当普遍的模式。我们在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;
}
想要查询更多的信息
在我们的应用程序中有一个相当常见的模式。我们在 Xml 中配置一组(或列表)对象,这些对象都实现了一个公共接口。在启动时,应用程序读取 Xml 并使用 JAXB 创建/配置对象列表。我从来没有想出(在多次阅读各种帖子之后)仅使用JAXB来做到这一点的“正确方法”。 例如,我们有一个接口,以及多个具体的实现类,它们具有一些共同的属性,以及一些不同的属性和非常不同的行为。我们用来配置应用程序使用的费用
问题内容: 如何使用Gson解析此JSON?我有一个具有多个对象类型的数组,但我不知道需要创建哪种对象来保存此结构。我无法更改json消息(我无法控制服务器)。 唯一起作用的类是 JSON消息 (请注意具有多个对象类型的数组。) 问题答案: 《 Gson用户指南》明确涵盖了以下内容: https://sites.google.com/site/gson/gson-user-guide#TOC-Se
问题内容: 例如: 因为json数组被解码为go数组,并且go数组需要显式定义类型,所以我不知道如何处理它。 问题答案: 首先,json无效,对象必须具有键,因此它应该类似于或just 。 而当您处理多种随机类型时,只需使用即可。
我从 3 个不同的客户端收到 3 个不同的 xml 输入: 来自客户端1的输入1:(命名空间前缀:,命名空间url:) 来自客户端 2 的输入 2:(命名空间前缀:,命名空间 URL:) 从客户端3输入3:(名称空间前缀: 时,< li >调用< code>String.replace() 这让我想到这种变量命名空间的方法是否应该完全可以接受。如果有什么可以改进此代码的方法,那么我要求社区在答案/
有太多关于大致相同主题的问题,但我找不到我想要的。如果我错过了,我很抱歉。 我正在尝试散集具有公共逻辑元素但使用不同标记定义的XML文件: 两个<代码> 我可以这样做: 所需要的只是在和中实现并分别返回或。 然而,在中有一个属性并以某种方式告诉JAXB将这两个字段映射到它似乎更简单。 我是不是想多了?你将如何实现它? (当然,我无法控制输入XML。如果可能的话,我还想避免使用MOXy的解决方案,因
问题内容: 我对此进行了扩展,应该可以帮助我在上下文之间传输对象: 现在它返回的对象,我应该将其强制转换为我想要的类,如下所示: 有没有办法避免这种无用的转换,如果我从类的对象调用使其返回类型? 问题答案: 更新: 有关更好的解决方案 与如何在NSManagedObjectSwift扩展中如何创建托管对象子类的实例中类似,这可以使用通用的辅助方法来完成: 请注意,我已将返回类型更改为。 并 没有