JAXB +枚举 +显示多个值

发布于 2024-09-19 02:32:14 字数 1209 浏览 0 评论 0原文

我有一个枚举:

@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>

我希望它同时输出枚举名称(即 POKER)和密钥(即“favourite-product-poker”) 。

我尝试了多种不同的方法来执行此操作,包括使用 @XmlElement、@XmlEnumValue 和 @XmlJavaTypeAdapter,但没有同时使用这两种方法。

有谁知道如何实现这一点,就像普通的 JAXB 带注释的 bean 一样?

谢谢。

I have an enum:

@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;
    }

that I output in a REST service like so:

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

and it outputs like this:

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

I want it to output with both the enum name (i.e, POKER) and the key (i.e, "favourite-product-poker").

I have tried a number of different ways of doing this including using @XmlElement, @XmlEnumValue and @XmlJavaTypeAdapter, without getting both out at the same time.

Does anyone know how to achieve this, as you would for a normal JAXB annotated bean?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久随 2024-09-26 02:32:14

您可以为此创建一个包装器对象,如下所示:

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 的实例而不是 Product 传递给 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);
    }

}

You could create a wrapper object for this, something like:

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();
    }

}

This would correspond to the following XML:

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

You would need to pass instances of ProductWrapper to JAXB instead of Product.

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);
    }

}
醉生梦死 2024-09-26 02:32:14

您可以使用适配器:

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);}};
}

You can use an adapter:

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);}};
}
孤云独去闲 2024-09-26 02:32:14

如果您希望像普通对象一样将其序列化为 XML,则需要从枚举值中删除 @XmlEnum。枚举(根据定义)在 XML 中由单个字符串符号表示。例如,这允许将其与 @XmlList 组合以创建高效的、以空格分隔的项目列表。

You need to remove the @XmlEnum from your enum value, if you want it to be serialized into XML like a normal object. An enum (by definition) is represented in the XML by a single string symbol. This allows combining it with @XmlList, for example, to create an efficient, whitespace-separated list of items.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文