Java 如何从JAXBContext中未使用的对象链接XmlElements?
在创建Marsaller时,是否有任何方法可以链接或引用JAXBContext中未使用的类中的XmlElements 我正在使用Jersey将JAXB注释对象转换为XML文件 这是我的设置。所有类都在同一个包中 对于Marsaller,我使用B、C或D类Java 如何从JAXBContext中未使用的对象链接XmlElements?,java,xml,jaxb,Java,Xml,Jaxb,在创建Marsaller时,是否有任何方法可以链接或引用JAXBContext中未使用的类中的XmlElements 我正在使用Jersey将JAXB注释对象转换为XML文件 这是我的设置。所有类都在同一个包中 对于Marsaller,我使用B、C或D类 @XmlAccessorType(XmlAccessType.NONE) class A { private Foo foo; public SomeObject getSomeObjetct() { retu
@XmlAccessorType(XmlAccessType.NONE)
class A {
private Foo foo;
public SomeObject getSomeObjetct() {
return foo.getSomeObjetct();
}
protected setFooBehavior(Foo f) {
this.foo = f;
}
/* From this point the XmlElements are commond to all subclasses
* and no other special manipulation take place.
*/
@XmlElement(...)
...someGetterMethod(){}
@XmlElement(...)
...someOtherGetterMethod(){}
@XmlElement(...)
...someThirdGetterMethod(){}
...
...
}
@XmlRootElement(name = "B")
class B extends A{
setFooBehavior(new FooA());
}
@XmlRootElement(name = "C")
class C extends A{
setFooBehavior(new FooA());
}
@XmlRootElement(name = "D")
class D extends A{
setFooBehavior(new FooB());
}
class FooA {
SomeObject someObject;
@XmlElement(name = "FooA", required = true)
public SomeObject getSomeObjetct() {
return getSomeObjetct();
}
public setSomeObject(SomeObject someObject;) {
this.someObject = SomeObject someObject;;
}
}
class FooB {
SomeObject someObject;
@XmlElement(name = "FooB", required = true)
public SomeObject getSomeObjetct() {
return getSomeObjetct();
}
public setSomeObject(SomeObject someObject;) {
this.someObject = SomeObject someObject;;
}
}
每种情况下的Marsaller都是
JAXBContext jaxbContext = JAXBContext.newInstance(C.class); //or B.class or D.class
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
最后,我希望得到以下xml结果
C类
<C>
<FooA>someObjectValue</FooA>
</C>
someObjectValue
D班呢
<D>
<FooB>someObjectValue</FooB>
</D>
someObjectValue
我现在得到的输出是
<C>
<someObject>someObjectValue</someObject>
<C>
someObjectValue
及
someObjectValue
分别。您提到某些对象需要在D中进行特殊处理。您还有一个Foo实例吗?你能做到:
public class A {
@XmlElementRef
public Foo getFoo() {
return foo;
}
@XmlTransient
public SomeObject getSomeObject() {
return foo.getSomeObject();
}
}
更新:如果您不能公开Foo,那么信息必须存储在其他机制中。以下解决方案不是很好,但可能有用:
public class A {
private Class<?> fooType;
//protected should be enough for JAX-B and will
//hide the method from the rest of your code.
@XmlAnyElement
protected JAXBElement<SomeObject> getSomeObjetctForJaxb() {
return new JAXBElement<SomeObject>(new QName(fooType.getSimpleName()), SomeObject.class, getSomeObjetct());
}
}
公共A类{
私有类足迹;
//对于JAX-B和will来说,受保护应该足够了
//对其余代码隐藏该方法。
@XmlAnyElement
受保护的JAXBElement getsomeobjetcforjaxb(){
返回新的JAXBElement(新的QName(fooType.getSimpleName())、SomeObject.class、getSomeObjetct();
}
}
您还需要解组XML吗?如果是这样,您将需要一个setter,它接受
JAXBElement
,并且必须根据元素的名称适当地创建Foo。我不确定是否理解您的问题。看起来FooA和FooB是JAXB注释的(它们在someObjetct上都有@xmlement)。你犯了什么样的错误?什么不起作用?为什么输出不是您期望的?我更改了描述,并编写了我期望的输出和我得到的输出。是的,我总是有一个Foo实例。不幸的是,我无法从中返回Foo!Foo用于模拟某个对象的不同行为。返回foo,要求在项目的很大一部分中更改代码。实际上,在fooasomeobject是一个对象的单个实例,而在foobsomeobject是同一个对象的列表。但是除了FooA和FooB,没有人应该知道这一点。当然,A的新子类可能具有单个对象或列表行为。好的,再试一次。恐怕这个班级结构有点复杂。对你的代码了解不够,我能想到的最好的办法是,在这种情况下,组合可能比继承更好。谢谢你的帮助。它解决了我的问题。我更改了类A中的getSomeObject方法以返回一个JAXBElement。我试图用XmlElementRef解决它,但运气不好。。。顺便说一句,我上面给出的结构正是我所拥有的。我刚改了名字:D!再次感谢!
public class A {
private Class<?> fooType;
//protected should be enough for JAX-B and will
//hide the method from the rest of your code.
@XmlAnyElement
protected JAXBElement<SomeObject> getSomeObjetctForJaxb() {
return new JAXBElement<SomeObject>(new QName(fooType.getSimpleName()), SomeObject.class, getSomeObjetct());
}
}