Java 使用泛型和基类时,Jaxb XML名称空间不正确

Java 使用泛型和基类时,Jaxb XML名称空间不正确,java,jaxb,jaxb2,Java,Jaxb,Jaxb2,我在两个名称空间中有四个类,一个包中的两个用作另一个包中两个的基类,例如: @XmlAccessorType(XmlAccessType.FIELD) public class Foo<T extends Bar> { @XmlElement(name="Bar") private List<T> bar; } 派生类如下所示: @XmlType(name="Foo" namespace="urn:foo/Bar") @XmlRootElement(

我在两个名称空间中有四个类,一个包中的两个用作另一个包中两个的基类,例如:

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo<T extends Bar> {

    @XmlElement(name="Bar")
    private List<T> bar;

}
派生类如下所示:

@XmlType(name="Foo" namespace="urn:foo/Bar")
@XmlRootElement(name="Foo")
public class DerivedFoo extends Foo<DerivedBar> {
    // something
}
在包含基类的包中,没有
package info.java
或任何包含名称空间信息的内容。包含派生类的包具有所有命名空间信息

输出XML对
DerivedFoo
类进行了适当的(排序)命名,但将
DerivedBar
类分配给了一个未命名的名称空间,基本上:

<Response xmlns:ns2="urn:foo/Bar">
  <ns2:Foo>
    <Bar>
    </Bar>
  </ns2:Foo>
</Response>

我认为您需要的是和的组合。使用
@xmlementref
注释就像说“这里有一件事;看看它的
@XmlRootElement
注释,找出如何序列化它。”

下面的设置似乎符合您的要求。基类:

package base;

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo<T extends Bar> {

    @XmlElementRef
    public List<T> bar;

}

从我的测试来看很不错:

@Test
public void tryIt() throws Exception {
    JAXBContext context = JAXBContext.newInstance(Request.class, DerivedFoo.class, DerivedBar.class);

    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    Request request = new Request();
    DerivedFoo foo = new DerivedFoo();
    request.foo = foo;
    foo.bar = new ArrayList<DerivedBar>();
    foo.bar.add(new DerivedBar());

    marshaller.marshal(request, System.out);
}

嵌套类型可能不太在意,但我打赌使用
Request
的人可能不会识别这些元素名称。

您能否分享重现问题的步骤(可能是命令行调用或maven插件配置)?
package base;

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo<T extends Bar> {

    @XmlElementRef
    public List<T> bar;

}
package base;

@XmlAccessorType(XmlAccessType.FIELD)
public class Bar {
    // something
}
package base;

@XmlRootElement(name = "Request")
@XmlAccessorType(XmlAccessType.FIELD)
public class Request {

    @XmlElementRef
    public Foo<?> foo;
}
package derived;

@XmlRootElement(name = "Foo", namespace = "urn:foo/Bar")
public class DerivedFoo extends Foo<DerivedBar> {
    // something
}
package derived;

@XmlRootElement(name = "Bar", namespace = "urn:foo/Bar")
public class DerivedBar extends Bar {
    // something
}
@Test
public void tryIt() throws Exception {
    JAXBContext context = JAXBContext.newInstance(Request.class, DerivedFoo.class, DerivedBar.class);

    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    Request request = new Request();
    DerivedFoo foo = new DerivedFoo();
    request.foo = foo;
    foo.bar = new ArrayList<DerivedBar>();
    foo.bar.add(new DerivedBar());

    marshaller.marshal(request, System.out);
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Request xmlns:ns2="urn:foo/Bar">
    <ns2:Foo>
        <ns2:Bar/>
    </ns2:Foo>
</Request>
<Request xmlns:ns2="urn:rock/roll" xmlns:ns3="urn:yummy">
    <ns2:FooFighters>
        <ns3:TikiBar/>
    </ns2:FooFighters>
</Request>