web-dev-qa-db-fra.com

java.util.List est une interface et JAXB ne peut pas gérer les interfaces

J'ai semblé obtenir l'exception suivante en essayant de déployer mon application:

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


Mon code a bien fonctionné jusqu'à ce que je change le type de retour de List en List <List <RelationCanonical>>

Voici le webservice partiel:


@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) {

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


J'ai également essayé en supprimant @SOAPBinding et en essayant par défaut, mais le même résultat se produit. Appréciez toute aide

MISE À JOUR

Je veux noter quelque chose. J'ai changé tout List en ArrayList, puis il a compilé. La raison pour laquelle je dis compilé et non travaillé, c'est parce qu'il se comporte bizarrement. J'obtiens un objet de type: RelationServiceStub.ArrayList mais l'objet n'a pas de méthodes get ou ne se comporte pas non plus comme une liste. J'ai également essayé de le jeter sur une liste, mais cela n'a pas fonctionné.

Notez que c'est après avoir utilisé Axis 2 et wsdl2Java Alors oui, maintenant il compile, mais je ne sais pas comment extraire les données.

45
Shervin Asgari

À ma connaissance, vous ne pourrez pas traiter un List simple via JAXB, car JAXB n'a aucune idée de comment le transformer en XML.

Au lieu de cela, vous devrez définir un type JAXB qui contient un List<RelationCanonical> (Je l'appellerai Type1), et un autre pour contenir une liste de ces types, à son tour (comme vous avez affaire à un List<List<...>>; Je vais appeler ce type Type2).

Le résultat pourrait alors être une sortie XML comme celle-ci:

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

Sans les deux types annotés JAXB, le processeur JAXB n'a aucune idée du balisage à générer et échoue donc.

--Éditer:

Ce que je veux dire devrait ressembler à ceci:

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

et

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

Vous devriez également consulter le section JAXB dans le tutoriel J5EE et le Guide JAXB non officiel .

26
Henning

Si cela convient à votre objectif, vous pouvez toujours définir un tableau comme celui-ci:

YourType[]

JAXB peut certainement comprendre ce que c'est et vous devriez pouvoir l'utiliser immédiatement côté client. Je vous recommanderais également de le faire de cette façon, car vous ne devriez pas être en mesure de modifier le tableau récupéré d'un serveur via une liste mais via des méthodes fournies par le service Web

8
Argo

Si vous voulez le faire pour n'importe quelle classe.

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