2008-11-18 63 views
40

Me parecía tener la siguiente excepción cuando se trata de desplegar mi aplicación:java.util.List es una interfaz, y JAXB no puede manejar las interfaces

Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of  IllegalAnnotationExceptions 
java.util.List is an interface, and JAXB can't handle interfaces. 
this problem is related to the following location: 
    at java.util.List 
    at private java.util.List  foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse._return 
    at  foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse 
java.util.List does not have a no-arg default constructor. 
    this problem is related to the following location: 
     at java.util.List 
     at private java.util.List foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse._return 
    at  foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse 


Mi código funcionaba bien hasta que he cambiado el tipo de retorno de la lista a la lista < Lista <RelationCanonical> >

Aquí es el servicio web parcial:


@Name("relationService") 
@Stateless 
@WebService(name = "RelationService", serviceName = "RelationService") 
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) 
public class RelationService implements RelationServiceLocal { 

    private boolean login(String username, String password) { 
     Identity.instance().setUsername(username); 
     Identity.instance().setPassword(password); 
     Identity.instance().login(); 
     return Identity.instance().isLoggedIn(); 
    } 

    private boolean logout() { 
     Identity.instance().logout(); 
     return !Identity.instance().isLoggedIn(); 
    } 

    @WebMethod 
    public List<List<RelationCanonical>> getRelationsFromPerson(@WebParam(name = "username") 
    String username, @WebParam(name = "password") 
    String password, @WebParam(name = "foedselsnummer") 
    String... foedselsnummer) { 

...... 
...... 
...... 
} 


También he intentado eliminar el @SOAPBinding y probar el valor predeterminado, pero ocurre el mismo resultado. agradecería cualquier ayuda

ACTUALIZACIÓN

quiero señalar algo. Cambié todas las listas a ArrayList, y luego las compilé. La razón por la que digo compilada y no funciona es porque se comporta de manera extraña. Obtengo un objeto de tipo: RelationServiceStub.ArrayList pero el objeto no tiene métodos de obtención o no se comporta como una lista. También traté de lanzarlo a una lista, pero eso no funcionó.

Tenga en cuenta que esto es después de haber usado Axis 2 y wsdl2java Entonces sí, ahora se compila, pero no sé cómo sacar los datos.

Respuesta

24

En mi entender, no podrá procesar un simple List a través de JAXB, ya que JAXB no tiene idea de cómo transformar eso en XML.

En su lugar, tendrá que definir un tipo de JAXB que tiene una List<RelationCanonical> (lo llamaré Type1), y otro para sostener una lista de esos tipos, a su vez (como se está tratando con un List<List<...>>; Llamaré a este tipo Type2).

El resultado podría ser una continuación ouput XML como esto:

<Type2 ...> 
    <Type1 ...> 
     <RelationCanonical ...> ... </RelationCanonical> 
     <RelationCanonical ...> ... </RelationCanonical> 
     ... 
    </Type1> 
    <Type1> 
     <RelationCanonical ...> ... </RelationCanonical> 
     <RelationCanonical ...> ... </RelationCanonical> 
     ... 
    </Type1> 
    ... 
</Type2> 

Sin los dos tipos de cerramiento anotado JAXB, el procesador JAXB tiene ni idea de lo marcado para generar, y por lo tanto falla.

--Editar:

Lo que quiero decir debe parecerse esto:

@XmlType 
public class Type1{ 

    private List<RelationCanonical> relations; 

    @XmlElement 
    public List<RelationCanonical> getRelations(){ 
     return this.relations; 
    } 

    public void setRelations(List<RelationCanonical> relations){ 
     this.relations = relations; 
    } 
} 

y

@XmlRootElement 
public class Type2{ 

    private List<Type1> type1s; 

    @XmlElement 
    public List<Type1> getType1s(){ 
     return this.type1s; 
    } 

    public void setType1s(List<Type1> type1s){ 
     this.type1s= type1s; 
    } 
} 

También debe revisar la JAXB section in the J5EE tutorial y la Unofficial JAXB Guide.

8

si que se adapte a su propósito siempre se puede definir una matriz de esta manera:

YourType[] 

JAXB sin duda puede averiguar lo que es y que debe ser inmediatamente pude utilizarlo lado del cliente.También le recomendaría hacerlo de esa manera, ya que no debería poder modificar la matriz recuperada de un servidor a través de una Lista, sino a través de los métodos provistos por el servicio web

1

Si desea hacer esto para cualquier clase.

return items.size() > 0 ? items.toArray((Object[]) Array.newInstance(
      items.get(0).getClass(), 0)) : new Object[0]; 
-6

Puede utilizar "ArrayList" en lugar de "lista" interno

+1

Sí ya he mencionado en la pregunta que hice esto, pero aún no funcionaba. Lee la actualización –

Cuestiones relacionadas