Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
8.9k views
in Technique[技术] by (71.8m points)

java - JAXB Can't handle interfaces

I think this question has been asked like a million times, but none of solutions suggested worked for me. Here is my sample implementation

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;
    }

I always get following exception

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions com.abc.objectsToReturn.Foo is an interface,

can any one help me to figure out right solution

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This isn't really an interface issue, you just need to change the way you bootstrap your JAXBContext.

If you change it to the following:

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);
    }
}

Then you will get the following output (with any JAXB implementation: Metro, MOXy, etc):

<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 allows your entire model to be interfaces, checkout:

I also have a blog post that may be relevant to what you are trying to build:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...