У меня есть следующий код:
private SetMultimap<String, Dynamic> dynamicFields = TreeMultimap.create(Ordering.natural(), new Comparator<Dynamic>() {
@Override
public int compare(Dynamic o1, Dynamic o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
});
который дает мне следующее исключение.
IllegalAnnotationsException SetMultimap is an interface, and JAXB can't handle interfaces
Мой вопрос, каким образом это не работает, но это делает:
List<Dynamic> test = new ArrayList<Dynamic>();
И как я могу зафиксировать SetMultimap так, чтобы JAXB был счастлив?
Разница между List/ArrayList и SetMultimap заключается в том, что один является коллекцией Java, а другой - структурой данных вне обычной иерархии коллекций Java. Это означает, что JAXB рассматривает их как обычный класс.
Спецификация JAXB не поддерживает интерфейсы. Вероятно, вы используете реализацию Metro JAXB, которая также не поддерживает интерфейсы. Некоторые реализации JAXB, такие как MOXy, могут поддерживать интерфейсы, но некоторые реализации JAX-WS зависят от конкретного JAXB impl, и замена реализаций JAXB не всегда возможна:
Лучше всего использовать аннотацию уровня параметров для преобразования SetMultimap в класс, который может быть обработан JAXB:
Вам необходимо добавить аннотации, чтобы сообщить JAXB о возможных типах времени выполнения ссылки, например:
@XmlElements({
@XmlElement(type = TreeMultimap.class, name = "treeMultimap"),
@XmlElement(type = MultiHashMap.class, name = "hashMultimap")
})
private SetMultimap<String, Dynamic> dynamicFields = TreeMultimap.create(Ordering.natural(), new Comparator<Dynamic>() {
@Override
public int compare(Dynamic o1, Dynamic o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
});
С помощью приведенного выше кода вы также можете заменить поле экземпляром MultiHashMap, если хотите. Вам необходимо добавить @XmlElement
для каждого возможного типа среды выполнения. Если вы никогда не будете использовать хеш-карту, достаточно одного @XmlElement
с TreeMultimap.class
:
@XmlElement(type = TreeMultimap.class, name = "treeMultimap")
private SetMultimap<String, Dynamic> dynamicFields = TreeMultimap.create(Ordering.natural(), new Comparator<Dynamic>() {
@Override
public int compare(Dynamic o1, Dynamic o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
});