我有一种情况,Java 对象包含Payload<T>需要编组为 xml 的泛型。所以给定以下类:
抽象框
@XmlTransient
public abstract class AbstractBox {
    String type = this.getClass().getSimpleName();
    String name = this.getClass().getCanonicalName();
    // setters/getters snipped
    public abstract String saySomething();
}
小盒子
@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在具体子类上使用来更改payload为,small-box但这也不起作用。如果我删除该Payload<P>对象并仅拥有一个  payload泛型类型 P 的类成员,则该paymentContainer标记将消失,但payload仍保留并且不使用small-box我指定的名称。
有没有办法让我强制 JAXB(任何实现)将标签设置为子类中指定的名称而不是泛型类型属性?
更新: 所选答案提供了解决方案,但我也想跟进问题。我的问题有两个:
- 我@XmlTransient在Payload<T>类上使用并且需要在方法上使用@XmlAnyElement注释setPayload(T payload)(尽管我怀疑 setter/getter 对的哪个方法被注释并不重要,只要只有一个具有注释)。
- 我使用的是 Jackson 2 JacksonJaxbXmlProvider,它是一个不完整的 JAXB 实现,它忽略了@XmlRootElement用作@XmlAnyElement-annotated 属性值的元素。
将我的 JAXB 提供程序更改为使用 Java 6/7 内置 JAXB 提供程序会生成我预期的输出。