有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JAXB将XML文档映射到Java对象

我正在尝试为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>

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

当服务器使用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将根节点的名称(“服务器信息”)放入“type”元素中? 我认为应该使用绑定文件(serverInformation.xjb)来完成,但我不知道如何做到这一点

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


共 (1) 个答案

  1. # 1 楼答案

    通过删除xsd文件中的“type”字段并添加包含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>