2008-11-18 6 views
40

я, казалось, получаю следующее исключение при попытке развернуть мое приложение:java.util.List представляет собой интерфейс, и JAXB не может обрабатывать интерфейсы

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 


Мой код работает только хорошо, пока я не изменил тип возвращаемого значения из списка в список < < Список RelationCanonical > >

Вот частичное вебсервис:


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

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


Я также попытался удалить @SOAPBinding и попробовать по умолчанию, но тот же результат. Цените помощь

UPDATE

Я хочу отметить, что-то. Я изменил все List на ArrayList, а затем скомпилировал. Причина, по которой я говорю, скомпилирована и не работает, связана с тем, что она ведет себя странно. Я получаю объект типа: RelationServiceStub.ArrayList но объект не имеет методов получения или не ведет себя как список либо. Я также попытался передать его в список, но это не сработало.

Обратите внимание, что это после того, как я использовал ось 2 и wsdl2java Так что да, теперь он собирает, но я не знаю, как получить данные из.

ответ

24

В моем понимании, вы не сможете обработать простой List через JAXB, поскольку JAXB не имеет понятия, как преобразовать его в XML.

Вместо этого, вам нужно будет определить тип JAXB, который держит List<RelationCanonical> (я буду называть его Type1), и еще один, чтобы держать список этих типов, в свою очередь (как вы имеете дело с List<List<...>>; Я назову этот тип Type2).

Результат может затем быть XML Ouput так:

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

Без двух вмещающих JAXB-аннотированных типов, процессор JAXB не имеет представления о том, что разметка для создания, и, таким образом, не удается.

--edit:

Что я имею в виду должен выглядеть примерно так:

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

и

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

Вы также должны проверить JAXB section in the J5EE tutorial и Unofficial JAXB Guide.

8

Если это подходит для ваших целей, вы всегда можете определить массив так:

YourType[] 

JAXB, безусловно, может понять, что это такое, и вы должны быть в состоянии немедленно использовать его на стороне клиента.Я бы также рекомендовал вам сделать это таким образом, так как вы не сможете изменять массив, полученный с сервера через список, но с помощью методов, предоставляемых веб-службой.

1

Если вы хотите сделать это для любого класса.

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

Вы можете использовать «ArrayList» вместо внутреннего «List»

+1

Да я уже упоминал в этом вопросе, что я сделал это, но он по-прежнему не работает. Прочтите обновление – 2013-09-13 13:01:04