XStream - Root как коллекция объектов - PullRequest
5 голосов
/ 29 июня 2010

Я использую полезную нагрузку XML, которая выглядит примерно так (для более полного примера посмотрите: http://api.shopify.com/product.html).

<products type="array">
   <product>
      ...
   </product>
   <product>
      ...
   </product>
</products>

Сейчас мой код работает, ноон делает что-то, что кажется действительно «неправильным», а именно - связывает «продукты» с List.class.Таким образом, соответствующий код выглядит следующим образом:

    xstream.alias( "products", List.class );
    xstream.alias( "product", ShopifyProduct.class );

Это хорошо, за исключением того, что когда я иду на экстернализацию любого объекта с этим экземпляром xstream, он всегда использует «продукты», что, конечно, не то, что я хочу.

Я хотел бы либо иметь возможность сопоставить родовые коллекции с тегом:

xstream.alias( "products", ( List<ShopifyProduct> ).class ); // way too easy 

Или заставить работать следующий фрагмент кода, который на данный момент не работает:

    ClassAliasingMapper mapper = new ClassAliasingMapper( xstream.getMapper( ) );
    mapper.addClassAlias( "product", ShopifyProduct.class );
    xstream.registerLocalConverter( ShopifyProductResponse.class, "products", new CollectionConverter( mapper ) );

Я создал класс ShopifyProductResponse, чтобы попытаться обернуть ShopifyProduct, но мне об этом ничего не сказано:

com.thoughtworks.xstream.mapper.CannotResolveClassException: products: products at com.thoughtworks.xstream.mapper.DefaultMapper.realClass (DefaultMapper.java:68) в com.thoughtworks.xstream.mapper.MapperWrapper.realClass (MapperWrapper.java:38)

Если я добавлю:

xstream.alias( "products", List.class );

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

1 Ответ

6 голосов
/ 29 июня 2010

Если я правильно понимаю, это то, что вы ищете. ShoppifyProductResponse.java

public class ShoppifyProductResponse {

private List<ShoppifyProduct> product;

/**
 * @return the products
 */
public List<ShoppifyProduct> getProducts() {
    return product;
}

/**
 * @param products
 *            the products to set
 */
public void setProducts(List<ShoppifyProduct> products) {
    this.product = products;
}

}

И конвертер для этого. UnMarshalling может выглядеть так.

public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    /**
     * Tune the code further..
     */
    ShoppifyProductResponse products = new ShoppifyProductResponse();
    List<ShoppifyProduct> lst = new ArrayList<ShoppifyProduct>();
    while (reader.hasMoreChildren()) {
        reader.moveDown();
        ShoppifyProduct thisProduct = (ShoppifyProduct) context.convertAnother(products,
                ShoppifyProduct.class);
        lst.add(thisProduct);
        reader.moveUp();
    }
    products.setProducts(lst);
    return products;
}

И вы можете зарегистрировать его как

    XStream stream = new XStream();
    stream.alias("products", ShoppifyProductResponse.class);
    stream.registerConverter(new ShoppifyConverter());
    stream.alias("product", ShoppifyProduct.class);

Я пробовал это, и это работает довольно хорошо. Попробуйте и дайте мне знать.

...