我有一种情况,其中一个Java对象包含需要编组到xml中的通用Payload<T>
。因此,考虑以下类:如何使用Java泛型指定JAXB元素的名称?
AbstractBox
@XmlTransient
public abstract class AbstractBox {
String type = this.getClass().getSimpleName();
String name = this.getClass().getCanonicalName();
// setters/getters snipped
public abstract String saySomething();
}
在smallBox
@XmlRootElement(name="small-box")
@XmlType(name="small-box")
public class SmallBox extends AbstractBox {
@XmlElement
public String getMsg() {
return saySomething();
}
public void setMsg(String msg) {
// do nothing
}
@Override
public String saySomething() {
return "I'm a small box";
}
}
有效载荷
@XmlTransient
public class Payload<T> {
private T payload;
public T getPayload() {
return payload;
}
public void setPayload(T payload) {
this.payload = payload;
}
}
和一些像这样的代码:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbAnnotationsTest<P>
{
String name;
int age;
int id;
Payload<P> payload;
// setters and getters snipped
public static void main(String[] args) {
JaxbAnnotationsTest<AbstractBox> example = new JaxbAnnotationsTest<AbstractBox>();
example.setName("Brion");
example.setId(100);
example.setAge(34);
Payload<AbstractBox> object = new Payload<AbstractBox>();
object.setPayload(new SmallBox());
example.setPayloadContainer(object);
try {
XmlMapper xmapper = new XmlMapper();
xmapper.writeValue(System.out, example);
} catch (Exception ex) {
System.err.println("Damn..." + ex.getMessage());
}
}
我希望看到:
<JaxbAnnotationsTest>
<name>Brion</name>
<age>34</age>
<id>100</id>
<payloadContainer>
<small-box>
<type>SmallBox</type>
<name>sandbox.xml.jaxb.annotations.SmallBox</name>
<msg>I'm a small box</msg>
</small-box>
</payloadContainer>
</JaxbAnnotationsTest>
而是我得到:
<JaxbAnnotationsTest>
<name>Brion</name>
<age>34</age>
<id>100</id>
<payloadContainer>
<payload>
<type>SmallBox</type>
<name>sandbox.xml.jaxb.annotations.SmallBox</name>
<msg>I'm a small box</msg>
</payload>
</payloadContainer>
</JaxbAnnotationsTest>
我使用@XmlType
于具体子类来试图改变到small-box
但是这也没有工作。如果我删除Payload<P>
对象,并且仅拥有泛型类型P的类成员,那么paymentContainer
标签将消失,但仍然存在,并且不使用我指定的small-box
名称。
有没有办法让我强制JAXB(任何实现)将标记设置为子类中指定的名称而不是泛型类型属性?
更新: 选定的答案提供了解决方案,但我想跟进问题以及。我的问题是双重的:
- 我在
Payload<T>
类使用@XmlTransient
并改用一个@XmlAnyElement
注解放在setPayload(T payload)
方法(虽然我怀疑它并不重要,其所需的setter /吸气对方法注释只要有一个注释)。 - 我使用的是Jackson 2的
JacksonJaxbXmlProvider
,这是一个不完整的JAXB实现,它忽略了用作@XmlAnyElement
-annated属性值的元素的@XmlRootElement
。
更改我的JAXB提供程序以使用Java 6/7内置JAXB提供程序生成我期望的输出。
我已经尝试过您的解决方案,它不会以任何不同的方式编组对象。我正在使用Jackson 2 JAXB库来执行JSON和XML编组。你用什么来获得这个示例代码来产生你的输出? – BrionS 2013-05-11 02:53:00
哦..你可能已经提到过:)我没有使用任何我尝试过使用JAXB标准JDK实现的库。它在JDK 6和7中工作正常 – 2013-05-11 08:55:23
有趣。我将尝试嵌入式JAXB实现和EclipseLink MOXy,因为我知道Jackson并未完全实现JAXB规范。谢谢! – BrionS 2013-05-11 11:26:26