2008-11-18 27 views
40

schien ich die folgende Ausnahme zu bekommen, wenn ich meine Anwendung bereitstellen:java.util.List ist eine Schnittstelle, und JAXB nicht verarbeiten kann Schnittstellen

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 


Mein Code nur gut funktioniert, bis ich geändert der Rückgabetyp von zur Liste < Liste <RelationCanonical> >

Hier ist die partielle webservice:


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

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


Ich habe auch versucht, indem Sie die @SOAPBinding und versuchen, Standard, aber das gleiche Ergebnis auftritt. jede Hilfe dankbar

UPDATE

Ich möchte etwas beachten, aus. Ich habe alle List in ArrayList geändert und dann kompiliert. Der Grund, warum ich kompiliert und nicht gearbeitet habe, ist, dass es sich merkwürdig verhält. Ich bekomme ein Objekt vom Typ: RelationServiceStub.ArrayList , aber das Objekt hat keine Methoden abrufen oder verhält sich nicht als eine Liste. Ich habe auch versucht, es auf eine Liste zu setzen, aber das hat nicht funktioniert.

Beachten Sie, dass dies nachdem ich Achse 2 und wsdl2java verwendet habe Also ja, jetzt kompiliert es, aber ich weiß nicht, wie Sie die Daten erhalten.

Antwort

24

In meinem Verständnis werden Sie nicht in der Lage sein, eine Ebene List über JAXB zu verarbeiten, da JAXB keine Ahnung hat, wie man das in XML umwandeln kann.

Stattdessen müssen Sie eine JAXB Typ definieren, die eine List<RelationCanonical> hält (Ich werde es Type1 nennen), und eine andere, eine Liste der Arten zu halten, die wiederum (wie Sie mit einem List<List<...>> zu tun hat; Ich rufe diesen Typ Type2).

Das Ergebnis ist dann ein XML-ouput so sein könnte:

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

Ohne die beiden umschließenden JAXB-kommentierten Typen hat der JAXB Prozessor keine Ahnung, welche Markup zu erzeugen, und nicht so.

--edit:

Was meine ich sollte etwas wie folgt aussehen:

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

und

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

Sie sollten auch die JAXB section in the J5EE tutorial überprüfen und die Unofficial JAXB Guide.

8

Wenn das Ihr Zweck passt können Sie immer ein Array wie folgt definieren:

YourType[] 

JAXB kann sicherlich herausfinden, was das ist, und Sie sollten es sofort in der Lage Client-Seite verwenden.Ich würde Ihnen auch empfehlen, dies so zu tun, da Sie das von einem Server abgerufene Array nicht über eine Liste ändern können, sondern über die vom Webservice bereitgestellten Methoden

1

Wenn Sie dies für eine beliebige Klasse tun möchten.

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

Sie können „Arraylist“ statt innere „List“ verwenden

+1

Ja ich schon in der Frage erwähnt, dass ich das tue, aber es immer noch nicht funktioniert. Lesen Sie das Update –