用 JAXB 和 Jersey 包装 XML 响应

Wrap XML response with JAXB and Jersey

我使用 Jersey 来实现我的 REST API 并且我有以下服务:

@Path("discoverytopology")
public class DiscoveryTopology {

    @GET
    @Produces("application/xml")
    public List<Definition> getDefinitionList() {
        List<Definition> definitions = db.getDefinitions();
        return definitions;
    }
}

Definition class 由 XML 注释注释并且 XML 中的响应包含许多定义,例如:

<defition body>
<defition body>
....

但我想要这样的东西,我需要为 XML 中的每个定义分配一个 ID,就像:

<DefinitionList>
    <definition id=1>
        <definition body>
    </definition>
    <definition id=2>
        <definition body>
    </definition>
    ............
</DefinitionsList>

我该怎么做?

您需要一个在 class 中表示您的 DefinitionList 的对象,该对象将用 @XMLRootElelement 注释,并且它必须包含 Definition

的列表

JAX-B 无法创建 <DefinitionList> 元素,除非它知道它存在。

然后您需要正确注释 Definition class 以便您的 <definition> 元素看起来像您想要的,属性与属性等

我不确定你的 <definition body> withtin <definition id="1"> 是否只是一个填充符,意思是 "body of defintion" 但如果不是,那么在其中包含 2 个具有不同定义的元素可能会很棘手相同的架构。不确定是否正确 XML.

创建包装器

创建一个 DefinitionWrapper class 注释如下:

@XmlRootElement(name = "DefinitionList")
@XmlAccessorType(XmlAccessType.FIELD)
public class DefinitionWrapper {

    @XmlElement(name = "definition")
    private List<Definition> definitions;

    public List<Definition> getDefinitions() {
        return definitions;
    }

    public void setDefinitions(List<Definition> definitions) {
        this.definitions = definitions;
    }
}

确保 Definition class 注释如下:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Definition implements Serializable {

    @XmlAttribute
    private Integer id;

    // Other fields

    // Getters and setters
}

并将您的端点方法更改为 return DefinitionWrapper:

@Path("discoverytopology")
public class DiscoveryTopology {

    @GET
    @Produces("application/xml")
    public DefinitionWrapper getDefinitionList() {
        List<Definition> definitions = db.getDefinitions();
        DefinitionWrapper definitionWrapper = new DefinitionWrapper;
        definitionWrapper.setDefinitions(definitions);
        return definitionWrapper;
   }
}

当编组为 XML 时,结果将是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DefinitionList>
    <definition id="1"/>
    <definition id="2"/>
    <definition id="3"/>
</DefinitionList>

添加元素

您可能需要 Definition class 中除 id 之外的其他字段。考虑一下,例如,您需要一个 description 字段,它应该被编组为一个 XML 元素。

为了实现它,请用 @XmlElement 注释您的字段,如下所示:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Definition implements Serializable {

    @XmlAttribute
    private Integer id;

    @XmlElement
    private String description;

    // Getters and setters
}

当编组为 XML 时,结果将是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DefinitionList>
    <definition id="1">
        <text>This is a description</text>
    </definition>
    <definition id="2">
        <text>This is a description</text>
    </definition>
    <definition id="3">
        <text>This is a description</text>
    </definition>
</DefinitionList>

添加一个值

您可以使用 @XmlValue 注释字段:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Definition implements Serializable {

    @XmlAttribute
    private Integer id;

    @XmlValue
    private String value;

    // Getters and setters
}

并且当您的对象被编组为 XML 时,结果将如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DefinitionList>
    <definition id="1">This is the value</definition>
    <definition id="2">This is the value</definition>
    <definition id="3">This is the value</definition>
</DefinitionList>

但是,每个 class 只允许一个用 @XmlValue 注释的字段。如果 class 有任何用 @XmlElement 注释的字段,它不能有任何用 @XmlValue.

注释的字段