2010-09-14 2 views
5

У меня есть перечисление:JAXB + Перечисления + Отображение нескольких значений

@XmlEnum 
@XmlRootElement 
public enum Product { 
    POKER("favourite-product-poker"), 
    SPORTSBOOK("favourite-product-casino"), 
    CASINO("favourite-product-sportsbook"), 
    SKILL_GAMES("favourite-product-skill-games"); 

    private static final String COULD_NOT_FIND_PRODUCT = "Could not find product: "; 

    private String key; 

    private Product(final String key) { 
     this.key = key; 
    } 

    /** 
    * @return the key 
    */ 
    public String getKey() { 
     return key; 
    } 

, что я выход в службе REST так:

GenericEntity<List<Product>> genericEntity = new GenericEntity<List<Product>>(products) { 
}; 
return Response.ok().entity(genericEntity).build(); 

и выводит как это:

<products> 
<product>POKER</product> 
<product>SPORTSBOOK</product> 
<product>CASINO</product> 
<product>SKILL_GAMES</product> 
</products> 

Я хочу, чтобы он выводился как с именем enum (т.е. POKER), так и с ключом (т. Е. «Любимый-продукт-покер»).

Я пробовал несколько различных способов сделать это, включая использование @XmlElement, @XmlEnumValue и @XmlJavaTypeAdapter, не получая оба одновременно.

Кто-нибудь знает, как достичь этого, как и для обычного аннотированного компонента JAXB?

Спасибо.

ответ

4

Вы можете создать объект-оболочку для этого, что-то вроде:

import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlValue; 

@XmlRootElement(name="product") 
public class ProductWrapper { 

    private Product product; 

    @XmlValue 
    public Product getValue() { 
     return product; 
    } 

    public void setValue(Product value) { 
     this.product = value; 
    } 

    @XmlAttribute 
    public String getKey() { 
     return product.getKey(); 
    } 

} 

Это будет соответствовать следующему XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<product key="favourite-product-poker">POKER</product> 

Вы должны пройти экземпляры ProductWrapper в JAXB вместо Продукт.

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(ProductWrapper.class); 

     ProductWrapper pw = new ProductWrapper(); 
     pw.setValue(Product.POKER); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.marshal(pw, System.out); 
    } 

} 
-1

Вы должны удалить @XmlEnum из вашего значения перечисления, если вы хотите, чтобы сериализовать в XML, как обычный объект. Перечисление (по определению) представлено в XML одним символом строки. Это позволяет комбинировать его с @XmlList, например, для создания эффективного списка элементов, разделенных пробелами.

2

Вы можете использовать адаптер:

import java.io.StringWriter; 
import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlElementWrapper; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlSeeAlso; 
import javax.xml.bind.annotation.XmlType; 
import javax.xml.bind.annotation.XmlValue; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

public class XmlEnumTest{ 

    public static void main(String...str) throws Exception{ 
     JAXBContext jc = JAXBContext.newInstance(ProductList.class); 
     StringWriter sw = new StringWriter(); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(new ProductList(),sw); 
     System.out.println(sw.toString()); 
    } 
} 

class ProductTypeAdaper extends XmlAdapter<ProductAdapter, Product> { 
    @Override 
    public Product unmarshal(ProductAdapter v) throws Exception { 
     return Product.valueOf(v.value); 
    } 

    @Override 
    public ProductAdapter marshal(Product v) throws Exception { 
     ProductAdapter result = new ProductAdapter(); 
     result.key = v.getKey(); 
     result.value = v.name(); 
     return result; 
    } 
} 

@XmlType 
class ProductAdapter{ 
    @XmlAttribute 
    public String key; 
    @XmlValue 
    public String value; 
} 

@XmlJavaTypeAdapter(ProductTypeAdaper.class) 
enum Product{ 
    POKER("favourite-product-poker"), 
    SPORTSBOOK("favourite-product-casino"), 
    CASINO("favourite-product-sportsbook"), 
    SKILL_GAMES("favourite-product-skill-games"); 

    private static final String COULD_NOT_FIND_PRODUCT = "Could not find product: "; 

    private String key; 

    private Product(final String key) { 
     this.key = key; 
    } 

    /** 
    * @return the key 
    */ 
    public String getKey() { 
     return key; 
    } 

} 

@XmlRootElement 
@XmlSeeAlso({Product.class}) 
class ProductList{ 
    @XmlElementWrapper(name="products") 
    @XmlElement(name="product") 
    private List<Product> list = new ArrayList<Product>(){{add(Product.POKER);add(Product.SPORTSBOOK);add(Product.CASINO);}}; 
} 
Смежные вопросы