Я пытаюсь обернуть 2 класса, построенные по шаблону Composite, с помощью JAXB.
Все это я построил так:
public interface ICriterion {String somemethod(String arg);}
@XmlRootElement(name = "criterion")
@XmlAccessorType(XmlAccessType.FIELD)
public class Criterion implements ICriterion {
@XmlElement String name;
@XmlElement String data;
//getter, setter, somemethod(), Criterion(), Criterion(String, String)
}
@XmlRootElement(name = "criteria")
@XmlAccessorType(XmlAccessType.FIELD)
public class Criteria implements ICriterion {
@XmlAnyElement(lax=true)
private final List<ICriterion> criteria;
//getter, setter, somemethod(),
Criteria(){criteria = new ArrayList<>();}
Criteria(List<ICriterion>)...
}
я взял это решение из этого ответа
Он отлично работает для сортировки - я могу предоставить критерии, которые содержат список критериев и критериев, он правильно маршалируется в xml.
Однако не работает преобразование строки в объект
String request =
<criteria>
<criteria>
<criterion>
<name>number1</value>
<data>123123</token>
</criterion>
<criterion>
<name>number2</value>
<data>1223323</token>
</criterion>
</criteria>
<criterion>
<name>number3</value>
<data>1212</token>
</criterion>
</criteria>
JAXBContext ctx = JAXBContext.newInstance(Criteria.class, Criterion.class);
StringReader reader = new StringReader(request);
Criteria wrapped = (Criteria) ctx.createUnmarshaller().unmarshal(reader);
дает:
java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
Я пробовал другие способы, доступные через онлайн-источники, такие как:
@XmlElementRefs({ @XmlElementRef(type=Criterion.class), @XmlElementRef(type=Criteria.class)})
@XmlElements({@XmlElement(type=Criteria.class),@XmlElement(type=Criterion.class)})
которые не выдают ошибку, но приводят к тому, что список становится пустым. Решение этой проблемы заключается в использовании @XmlAnyElement(lax=true)
, который мне не подходит.
Мое первое предположение заключалось в том, что список каким-то образом неправильно инициализирован в моем конструкторе, а JAXB использует какой-то список фиксированного размера. Моя контрмера заключалась в том, чтобы явно инициализировать список в конструкторе без аргументов.
Criteria(){criteria = new ArrayList<>();}
Проблема также не решается путем явного указания "critera" на ArrayList<>
вместо List<>
.
Что мне не хватает?