@XmlSeeAlso альтернатива - PullRequest
       3

@XmlSeeAlso альтернатива

6 голосов
/ 30 ноября 2011

У меня есть следующее:

class A{
    @XmlElement
    String name;

    //getters and setters
}

и

class B extends A{
    @XmlElement
    String height;

    //getters and setters
}

наконец у меня есть

@XmlRootElement
class P{
    @XmlElement
    List<A> things;

    //getters and setters
}

Если я сделаю

List<A> l = new ArrayList<A>();
l.add(new B('hello', 20)) //Add new B with height of 20 and name hello

P p = new P();
p.setThings(l); //Set things to list of B's.

и маршал P, я получаю поле только как часть вещей, а не высоту.

Я знаю, что могу добавить @XmlSeeAlso (B.class) в A, и все будет работать.

Но проблема в том, что я не знаю всех расширенных классов, кроме B, поскольку A. может быть расширен во время выполнения.

Как динамически определить @XmlSeeAlso во время выполнения?

Ответы [ 2 ]

2 голосов
/ 30 ноября 2011

Это зависит от того, как вы создаете JAXBContext . метод newInstance может вызываться с явным списком всех ваших классов, документация для этого метода также приводит аналогичный пример.

Клиентское приложение должно предоставить список классовчто новый объект контекста должен распознать.Не только новый контекст распознает все указанные классы, но он также распознает любые классы, на которые статически / косвенно ссылаются статически из указанных классов.Подклассы ссылочных классов и @XmlTransient ссылочных классов не зарегистрированы в JAXBContext.Например, в следующем Java-коде, если вы делаете newInstance (Foo.class), вновь созданный JAXBContext будет распознавать как Foo, так и Bar, но не Zot или FooBar:

class Foo {
    @XmlTransient FooBar c;
    Bar b;
}
class Bar { int x; }
class Zot extends Bar { int y; }
class FooBar { }

Редактировать: Если вам известны хотя бы имена пакетов потенциальных классов jaxb, вы также можете создать контекст с заданным путем к контексту .

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

Set<Class> classes = new HashSet<Class>();
classes.add(p.getClass());
for (A a : p.getThings()) {
    classes.add(a.getClass());
}
JAXBContext context = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]));
1 голос
/ 25 января 2012

Обратите внимание, что @XmlSeeAlso также может быть аннотировано на веб-сервисе, см. Этот пост: http://weblogs.java.net/blog/kohlert/archive/2006/10/jaxws_and_type.html

Это полезно, если ваш базовый класс не имеет доступа к подклассам (например, потому что они находятся в другом модуле), но ваш веб-сервис имеет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...