java.util.List - это интерфейс, а JAXB не может обрабатывать интерфейсы - PullRequest
44 голосов
/ 18 ноября 2008

При попытке развернуть мое приложение я получил следующее исключение:

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

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

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

Ответы [ 4 ]

25 голосов
/ 18 ноября 2008

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

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

Результатом может быть вывод XML, подобный следующему:

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

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

- Изменить:

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

@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 в руководстве по J5EE и Неофициальным руководством по JAXB .

8 голосов
/ 13 июля 2009

Если это соответствует вашим целям, вы всегда можете определить массив следующим образом:

YourType[]

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

1 голос
/ 01 ноября 2011

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

return items.size() > 0 ? items.toArray((Object[]) Array.newInstance(
            items.get(0).getClass(), 0)) : new Object[0];
0 голосов
/ 12 сентября 2013

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

...