Работа с JAXB, стандартный способ работы со списком «вложенных» представлений ресурсов (например, <products><product>X</product><product>Y</product></products>
- создать объект-оболочку, который в Java может выглядеть следующим образом (заимствовано из Jhopify ):
@XmlType(name = "")
@XmlRootElement(name = "products")
public class ProductList {
List<Product> products = new ArrayList<Product>();
@XmlElement(name = "product", required = true)
public List<Product> getProducts() { return products; }
public void setProducts(List<Product> products) { this.products = products; }
}
Однако я изо всех сил пытаюсь точно определить, какие объекты коллекции использовать при переводе в Scala. В блоге Mostly Blather есть хорошая вступительная статья, в которой используется итерация Scala, неявно преобразуемая (с использованием JavaConversions) в JCollection и из нее.
Это прекрасно работает для маршалинга класса JAXB в XML, но, к сожалению, при демаршаллинге это выдает UnsupportedOperationException
при каждой попытке add
. На основании последнего абзаца на этой странице документации Scala похоже, что это происходит потому, что Java не различает изменяемые и неизменяемые коллекции по их типу.
Чтобы разобраться с демаршалингом, я попробовал альтернативный подход, специально использующий изменяемые объекты:
@XmlType(name = "")
@XmlRootElement(name = "products")
class ProductList {
private var products: Buffer[Product] = new ArrayBuffer[Product]
@XmlElement(name = "product", required = true)
def getProducts: JList[Product] = products
def setProducts(products: JList[Product]) {
this.products = products
}
}
Но, к сожалению, при таком подходе unmarshalling дает мне исключение:
java.lang.NoSuchMethodError: ProductList.getProducts()Ljava/util/Collection;
Редактировать: в соответствии с запросом Трэвиса, вот мой код демаршаллинга:
val jaxbContext = JAXBContext.newInstance(ProductList.getClass())
val unmarshaller = jaxbContext.createUnmarshaller()
val root = unmarshaller.unmarshal(new StreamSource(new StringReader(responseString)), ProductList.getClass())
val r = root.getValue().asInstanceOf[ProductList]
val representations = r.getProducts.asScala.toList // Uses scalaj
Так что я немного озадачен ... Я тоже посмотрел на доступные конверсии scalaj , но ничего очевидного не выскакивает. Любая помощь высоко ценится!