作者:浪奔西安 | 来源:互联网 | 2024-12-20 12:22
本文探讨了如何在Java中使用JAXB解组两个具有相同名称但不同结构的对象。我们将介绍一个抽象类Bar及其具体实现,并展示如何正确地解析XML文档以获取正确的对象实例。
在Java应用程序中,有时需要处理具有相同名称但内部结构不同的JAXB对象。例如,我们有一个名为Bar的抽象类,其中包含一个带有@XmlElement注解的字符串属性val。
```java
public abstract class Bar {
@XmlElement
private String val;
}
```
该抽象类有两个具体的实现:BarA和BarB。每个子类都用@XmlRootElement注解标记为'bar',但它们之间存在细微差别。
```java
@XmlRootElement(name = "bar")
public class BarA extends Bar {
}
@XmlRootElement(name = "bar")
public class BarB extends Bar {
@XmlElement(required = true)
private String type;
}
```
为了从XML文件中正确解组这些对象,我们需要定义一个包含这些对象列表的类。以下是一个示例代码片段,展示了如何配置Bars类以支持多个类型的Bar对象。
```java
@XmlRootElement
public class Bars {
@XmlElementRefs({
@XmlElementRef(type = BarA.class),
@XmlElementRef(type = BarB.class)
})
private List bars;
}
```
然而,在实际应用中,我们可能会遇到一个问题:无论哪个是@XmlElementRefs链中的最后一个元素,似乎只会获得BarA或BarB的实例。这是因为JAXB默认情况下仅根据XML元素名称进行匹配,而不考虑具体的类型信息。
为了解决这个问题,可以采用以下方法之一:
1. **自定义适配器**:创建一个自定义的XmlAdapter来处理特定类型的转换。
2. **使用命名空间**:通过引入命名空间区分同名但不同类型的元素。
3. **添加额外的标识符**:在XML中添加额外的属性或元素,用于明确指定每个条目的类型。
下面是一个简单的测试代码,用于验证上述问题。
```java
String xml = ...;
JAXBContext jc = JAXBContext.newInstance(Bars.class);
ByteArrayInputStream in = new ByteArrayInputStream(xml.getBytes());
Bars bars = (Bars) jc.createUnmarshaller().unmarshal(in);
for (Bar bar : bars.getBars()) {
System.out.println(bar.getClass());
}
```
通过这些改进措施,您可以确保在解组过程中正确识别并实例化所需的对象类型。