我认为这个问题已被问过一百万次,但没有一个解决方案对我有用。这是我的示例实现
public class FooImpl2 implements Foo {
private int a = 100 ;
private String b = "I am FooImpl2";
private boolean c;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public boolean isC() {
return c;
}
public void setC(boolean c) {
this.c = c;
}
}
@XmlRootElement
@XmlSeeAlso({FooImpl1.class, FooImpl2.class})
public interface Foo {}
public class FooImpl1 implements Foo {
private int x;
private String y ="I am FooImpl1";
private boolean z;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
public boolean isZ() {
return z;
}
public void setZ(boolean z) {
this.z = z;
}
}
@XmlRootElement
public class Response{
private Foo foo;
@XmlElement(type=Object.class)
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
public class SimpleResource {
@Path("foo/{val}") @Produces({"application/json"}) @GET
public FooAdapter getFoo(@QueryParam("val") int val) {
FooAdapter ret = new FooAdapter();
if(val % 2 == 0) {
ret.setFoo(new FooImpl2());
} else {
ret.setFoo(new FooImpl1());
}
return ret;
}
我总是得到以下异常
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:2计数 IllegalAnnotationExceptions com.abc.objectsToReturn.Foo是一个 接口,
任何人都可以帮我找出正确的解决方案
答案 0 :(得分:6)
这不是一个真正的接口问题,您只需要改变引导JAXBContext的方式。
如果您将其更改为以下内容:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Response.class, FooImpl1.class, FooImpl2.class);
Response response = new Response();
FooImpl1 foo = new FooImpl1();
response.setFoo(foo);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
}
然后您将获得以下输出(使用任何JAXB实现:Metro,MOXy等):
<response>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="fooImpl1">
<x>0</x>
<y>I am FooImpl1</y>
<z>false</z>
</foo>
</response>
MOXy JAXB允许您的整个模型成为接口,结帐:
我还有一篇博文,可能与您要构建的内容相关:
答案 1 :(得分:3)
当你使用接口来隐藏你的实现类时,以及当一个类和一个接口之间存在1对1(或接近1对1)的关系时,可以像下面一样使用XmlJavaTypeAdapter。
@XmlJavaTypeAdapter(FooImpl.Adapter.class)
interface IFoo {
...
}
class FooImpl implements IFoo {
@XmlAttribute
private String name;
@XmlElement
private int x;
...
static class Adapter extends XmlAdapter<FooImpl,IFoo> {
IFoo unmarshal(FooImpl v) { return v; }
FooImpl marshal(IFoo v) { return (FooImpl)v; }
}
}
class Somewhere {
public IFoo lhs;
public IFoo rhs;
}