【问题标题】:JAXB mapping XML document to Java ObjectJAXB 将 XML 文档映射到 Java 对象
【发布时间】:2015-02-18 16:27:20
【问题描述】:

我正在尝试为 REST 服务制作一个简单的客户端示例。 服务器可以以 XML 和 JSON 格式发送响应。我无法改变服务器的行为。

我声明了我的元素:

    <xsd:complexType name="ServerInformation">
    <xsd:sequence>
        <xsd:element name="type" type="xsd:string"/>
        <xsd:element name="name" type="xsd:string" />
        <xsd:element name="version" type="xsd:string" />
        <xsd:element name="zone" type="xsd:string" />
        <xsd:element name="date" type="xsd:dateTime" />
        <xsd:element name="timeout" type="xsd:int" />
    </xsd:sequence>
</xsd:complexType>

我只有“类型”字段有问题。当服务器以 JSON 响应回答时,我有一个 "type" : "server_information" 节点。所以映射被正确地制作成Java。我可以调用方法 foo.getType() 并返回“server_information”。这是预期的行为。

当服务器以 XML 响应响应时,我也想这样做。问题是我没有名为“type”的节点。类型值包含在 XML 答案的根节点中。 这里是 XML 答案:

<server_information>
      <name>Server Name</name>
      <version>[development build]</version>
      <zone>Europe/Paris</zone>
      <date>2015-02-18T16:15:35.892Z</date>
      <timeout>300</timeout>
</server_information>

我对其他元素(名称、版本、区域...)的映射没有任何问题。只有类型。

所以我的问题是,如何指定 JAXB 以将根节点的名称(“server_information”)放入“type”元素中? 我认为应该使用绑定文件(serverInformation.xjb)来完成,但我不知道该怎么做......

我还需要兼容 JSON 和 XML。所以在 JSON 中,我仍然可以使用“类型”节点。

【问题讨论】:

  • 您是否尝试对 XML 和 JSON 使用相同的 JAXB 对象?
  • 如果需要,我可以为 WADL 描述使用单独的文件,但在 Java 中,我只想要一个包含所有字段的对象。 JSON 对象已经正确,我只需要能够获取 XML 文件的根名称并将其放入字段“类型”中。
  • 说实话,我认为这不值得。我会选择 JSON 或 XML 并坚持下去。如果您正在制作客户端 sample,只需制作两种类型中的一种。服务器是否尊重 Accept: 标头?
  • 是的,服务器接受“Accept”标头。我当前的项目只是一个示例,但之后我必须实现一个真正的客户端,然后才能选择格式(XML 或 JSON)。
  • 是的,所以我建议创建只使用您喜欢的格式的真实客户端。

标签: java xml jaxb cxf wadl


【解决方案1】:

我通过删除 xsd 文件中的“类型”字段并添加包含 XML 根元素的 Java 注释解决了我的问题。

我现在可以使用这个注解的值来获取类型。我所有的实体都使用“getType()”方法扩展了一个抽象类。

@XmlRootElement(name = "server_information")
public class ServerInformation extends AbstractEntityBase
{...}

每个实体的抽象类:

public abstract class AbstractEntityBase{

public final String getType(){
    return getClass().getAnnotation(XmlRootElement.class).name();
}

}

xsd 文件:

    <xsd:complexType name="server_information">
    <xsd:sequence>
        <xsd:element name="version" type="xsd:string" />
        <.../>
    </xsd:sequence>
</xsd:complexType>

xsd 绑定文件:

    <jaxb:bindings schemaLocation="ServerInformation.xsd" node="/xsd:schema/xsd:complexType[1]">

    <annox:annotate target="class">
        @javax.xml.bind.annotation.XmlRootElement(name = "server_information")
    </annox:annotate>

    <annox:annotate target="class">
        @com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown = true, value = {"type"})
    </annox:annotate>

    <jaxb:globalBindings>
        <xjc:superClass name="com.foo.AbstractEntityBase" />
    </jaxb:globalBindings>
</jaxb:bindings>

【讨论】:

    猜你喜欢
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多