Java JAXB继承冲突-子类上的重新注释
目前,我的项目中有以下环境:Java JAXB继承冲突-子类上的重新注释,java,xml,jaxb,Java,Xml,Jaxb,目前,我的项目中有以下环境: public abstract class Foo { private List<Thing> things; public List<Thing> getThings() { return this.things; } } public abstract class Bar extends Foo { @XmlElements({@XmlElement(name = "first", type = First.c
public abstract class Foo {
private List<Thing> things;
public List<Thing> getThings() { return this.things; }
}
public abstract class Bar extends Foo {
@XmlElements({@XmlElement(name = "first", type = First.class)})
public List<Thing> getThings() { return super.getThings(); }
}
public class Bobar extends Bar {
@XmlElements({@XmlElement(name = "second", type = Second.class)})
public List<Thing> getThings() { return super.getThings(); }
}
条形码对象在集合中只有一个元素,而不是两个。当我尝试执行object.getThings()
时,First
元素完全丢失,它的大小是1,集合中唯一的对象是Second
的实例。有人能帮助我如何在集合中获得这两个对象吗?如果这是不可能的,我怎样才能实现类似的目标
我这样做的原因是(在我的项目逻辑中)每个Bobar
s things集合在其集合中都有一个First
,但不是每个Bar
在其集合中都有一个Second
,并且Foo
是一个泛型类
编辑:
当我更改XML文档中的顺序时,输出是不同的
<bobar>
<second>blablabla</second>
<first>blublublu</first>
</bobar>
如果我这样做
<bobar>
<third>bliblibli</third>
<second>blablabla</second>
<first>blublublu</first>
</bobar>
blibili
喋喋不休
布鲁
理论上,我认为这不应该根据它生成的XML模式进行验证,因为这里的顺序不正确。但除此之外,在这种情况下,我得到了
第二个
和第一个
,第三个丢失了。下面是如何利用@xmltransive
映射这个用例的:
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class First extends Thing {
}
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Second extends Thing {
}
Bobar
您无法在子类中扩展映射,因此需要确保在执行@xmlmelements
映射时,您可以完成所有操作(请参阅:)
演示
package forum11698160;
import java.util.*;
public abstract class Foo {
private List<Thing> things = new ArrayList<Thing>();
public List<Thing> getThings() {
return this.things;
}
}
package forum11698160;
import java.util.*;
public abstract class Foo {
private List<Thing> things = new ArrayList<Thing>();
public List<Thing> getThings() {
return this.things;
}
}
以下演示代码可用于演示一切工作正常:
package forum11698160;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Bobar.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum11698160/input.xml");
Bobar bobar = (Bobar) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(bobar, System.out);
}
}
package forum11698160;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Bobar.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum11698160/input.xml");
Bobar bobar = (Bobar) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(bobar, System.out);
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8"?>
<bobar>
<first/>
<second/>
</bobar>
package forum11698160;
public class First implements Thing {
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
<first/>
<second/>
</bobar>
首先
<?xml version="1.0" encoding="UTF-8"?>
<bobar>
<first/>
<second/>
</bobar>
package forum11698160;
public class First implements Thing {
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
<first/>
<second/>
</bobar>
秒
package forum11698160;
public class Second implements Thing {
}
不可能对超级类型上的属性进行注释,也不可能以增量方式将子类型添加到该映射中。下面是一种支持您所关注的所有用例的方法。需要注意的一点是,对象层次结构中的所有级别都支持相同的元素集。您需要使用外部验证手段来限制所需的值 如果
Thing
是一个类而不是一个接口,并且第一个和第二个扩展Thing
,那么您可能有兴趣使用@xmlementref
而不是@xmlements
(请参阅:)。它将为您提供更大的灵活性,但需要进行一些验证(很难限制有效值集)
栏
我们将用@xmltransive
注释条
,以便JAXB实现不会处理它
package forum11698160;
import java.util.List;
import javax.xml.bind.annotation.XmlTransient;
@XmlTransient
public abstract class Bar extends Foo {
public List<Thing> getThings() {
return super.getThings();
}
}
东西
package forum11698160;
public interface Thing {
}
由于JAXB实现不能使用反射来查找类型的所有子类,因此我们可以使用@xmlseea
注释来提供帮助。如果不使用此注释,则在引导JAXBContext
时需要包含所有子类型
package forum11698160;
import javax.xml.bind.annotation.XmlSeeAlso;
@XmlSeeAlso({First.class, Second.class})
public class Thing {
}
首先
<?xml version="1.0" encoding="UTF-8"?>
<bobar>
<first/>
<second/>
</bobar>
package forum11698160;
public class First implements Thing {
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
<first/>
<second/>
</bobar>
我们需要首先用@XmlRootElement
注释:
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class First extends Thing {
}
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Second extends Thing {
}
秒
package forum11698160;
public class Second implements Thing {
}
Second
还需要用@XmlRootElement
注释:
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class First extends Thing {
}
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Second extends Thing {
}
演示
package forum11698160;
import java.util.*;
public abstract class Foo {
private List<Thing> things = new ArrayList<Thing>();
public List<Thing> getThings() {
return this.things;
}
}
package forum11698160;
import java.util.*;
public abstract class Foo {
private List<Thing> things = new ArrayList<Thing>();
public List<Thing> getThings() {
return this.things;
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8"?>
<bobar>
<first/>
<second/>
</bobar>
package forum11698160;
public class First implements Thing {
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
<first/>
<second/>
</bobar>
其他文件
以下是运行此示例所需的其他文件:
Foo
package forum11698160;
import java.util.*;
public abstract class Foo {
private List<Thing> things = new ArrayList<Thing>();
public List<Thing> getThings() {
return this.things;
}
}
package forum11698160;
import java.util.*;
public abstract class Foo {
private List<Thing> things = new ArrayList<Thing>();
public List<Thing> getThings() {
return this.things;
}
}
UM11698160的包;
导入java.util.*;
公共抽象类Foo{
private List things=new ArrayList();
公共列表getThings(){
归还这个东西;
}
}
我知道并且正在使用这种方法,但是如果我想扩展Bobar
,并在可能的事情列表中添加一个新元素,有什么方法可以做到吗?@SHiRKiT-我已经添加了第二个答案()。它使用@xmlementref
,这将以较少的验证为代价为您提供更大的灵活性。@blaise doughan是否可以从xsd和必要的绑定文件生成上述映射?或者可以手动完成吗?嗯,我发现我不能做我想做的事。我只是不明白为什么它不能按预期的方式工作。我想做的是在清单上增加更多的可能性。我不明白为什么如果我对Bobar
进行扩展,让我们称之为Fobar
,并用@xmlmelements
注释getThings
,列表不会同时包含Bobar
和Fobar
中的元素,因为在XML模式中,所有这些属性都会显示出来,因为它是一个扩展。模式生成正确,问题是当JAXB解组时,就会发生这种情况。我很难过,真的很难过=\在XML模式中,我将Fobar
作为complexType,使用complexContent和Bobar
作为扩展基础Fobar
将在序列中包含元素第三个
,而Bobar
包含元素第一个
和第二个
。我认为JAXB为Bobar
实例化了一个列表并将元素放入其中,然后为Fobar
实例化了另一个列表并放入元素,但是如果更改元素的顺序,就会发生一些奇怪的事情。我想那时候我只能忍受了。谢谢你的回答和时间!