2010-11-04 38 views
14

Creo que esta pregunta se ha formulado como un millón de veces, pero ninguna de las soluciones sugeridas me ha funcionado. Aquí está mi ejemplo de implementaciónJAXB No se pueden manejar las interfaces

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

Siempre me siguiente excepción

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 cargos de IllegalAnnotationExceptions com.abc.objectsToReturn.Foo es una interfaz ,

puede cualquiera que me ayude a encontrar la solución correcta

+0

¿Esto también falla si se trata de una clase abstracta? – Woot4Moo

+0

@ La sugerencia de Woot4Moo es lo que he encontrado con JAXB: interface = does not work, abstract class = works – Ash

Respuesta

6

Esto no es realmente un problema de interfaz, solo necesitas cambiar la forma en que arrancas tu JAXBContext.

Si lo cambia a lo siguiente:

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

por lo que recibirá la siguiente salida (con cualquier aplicación JAXB: Metro, , 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 permite a su todo el modelo para ser interfaces, pago y envío:

que también tienen un blog que puede ser relevante para lo que está tratando de construir:

+0

Blaise gracias por el ejemplo, sin embargo, esto no resolvió mi problema :( – user497760

+0

¿Qué problemas te encontraste? deberá incluir el eclipselink.jar en su ruta de clase, agregar el jaxb.properties apropiado e implementar ObjectFactory para devolver instancias de las clases impl. –

+0

No veo referencias a clases de eclipselink.jar en el código de muestra . También, ¿cómo sabe ObjectFactory que tiene que recoger jaxb.properties? – user497760

3

Al utilizar las interfaces simplemente para ocultar sus clases de implementación de la exposición, y cuando hay una relación de 1 a 1 (o cerca de 1 a 1) entre una clase y una interfaz, XmlJavaTypeAdapter se puede utilizar como a continuación.

@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; 
} 
+1

que es una copia exacta de: https://jaxb.java.net/guide/Mapping_interfaces.html#Use__XmlJavaTypeAdapter. Siempre debes citar tus fuentes – Murmel

Cuestiones relacionadas