java - JAXB:将 XML 标记放在抽象类上

标签 java xml inheritance jaxb

我正在使用来自第三方的接口(interface),他们有一种特殊的(至少在我看来)用于请求/响应和通知的 XML 格式。 XML 需要如下所示:

<Message>
  <Version>3.1</Version>
  <Request>
    <Request_Name>
      <RequestID> Request ID </RequestID>
      ...
    </Request_Name>
  </Request>
</Message>

Request 标记也可以是 NotificationResponse 之一。所有消息都只有这三者之一。 RequestResponse 都有 RequestIDResponse 也有 ReturnValue通知有一个 session

为了防止重复,我想为这三种类型中的每一种创建一个抽象类,而且它几乎可以工作!我可以编码和解码的内容如下所示:

<Message>
  <Version>3.1</Version>
  <Request_Name>
    <RequestID> Request ID </RequestID>
    ...
  </Request_Name>
</Message>

请注意缺少的 Request 标记!对于通知响应也是如此。所有信息都在那里,但这些包装标签快要杀了我!

问题: 我可以在抽象类上放置 XML 标记吗?或者我是否需要使其成为非抽象并创建另一个顶级抽象类作为“真正的”抽象基类?

我对 JAXB 没有太多经验,所以我希望有一种简单的方法来做到这一点。我尝试将消息上的 request 字段改为 XMLElement,但这只会将 Request_Name 标记更改为 Request 并添加类型规范。

我的代码基本上如下所示,为了简洁起见,删除了 setter 和 CTOR。

基本Message类:

@XmlRootElement(name = "Message")
public class Message {
    @XmlElement(required = true, name = "Version") private String version;
    private Request request;
    private Response response;
    private Notification notification;

    @XmlElementRef(required = false)
    public Request getRequest() {
        return request;
    }

    @XmlElementRef(required = false)
    public Response getResponse() {
        return response;
    }

    @XmlElementRef(required = false)
    public Notification getNotification() {
        return notification;
    }
}

抽象Request类。与通知响应类似:

@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public abstract class Request {
    private String requestId;

    @XmlElement(name = "RequestID", required = true)
    public String getRequestId() {
        return requestId;
    }
}

请求实现示例:

@XmlRootElement(name = "RegForAllNotificationsRequest")
public class RegForAllNotificationsRequest extends Request {
    private long session;
    private boolean register;

    @XmlElement(name = "SessionToUse")
    public long getSession() {
        return session;
    }
    @XmlElement(name = "Register")
    public boolean isRegister() {
        return register;
    }
}

上面的内容整理如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Message>
    <Version>8.3</Version>
    <RegForAllNotificationsRequest>
        <RequestID>94668</RequestID>
        <SessionToUse>548248</SessionToUse>
        <Register>true</Register>
    </RegForAllNotificationsRequest>
</Message>

我需要这个的地方:

<?xml version="1.0" encoding="UTF-8"?>
<Message>
    <Version>8.3</Version>
    <Request>
        <RegForAllNotificationsRequest>
            <RequestID>94668</RequestID>
            <SessionToUse>548248</SessionToUse>
            <Register>true</Register>
        </RegForAllNotificationsRequest>
    </Request>
</Message>

最佳答案

这里您需要的是一个具有标签名称RequestRequestContainer类。此类将包含实际的请求实现。这是必需的,因为 JAXB 会将每个类呈现为单独的标记。标签层次结构不是基于类层次结构构建的。

容器类看起来像这样:

@XmlRootElement(name = "Request")
public class RequestContainer {
   private Request request;
}

类似地,对于通知响应Message 类将包含每个容器类的实例,如下所示:

@XmlRootElement(name = "Message")
public class Message {
    @XmlElement(required = true, name = "Version") private String version;
    private RequestContainer request;
    private ResponseContainer response;
    private NotificationContainer notification;

    @XmlElementRef(required = false)
    public Request getRequest() {
        return request;
    }

    @XmlElementRef(required = false)
    public Response getResponse() {
        return response;
    }

    @XmlElementRef(required = false)
    public Notification getNotification() {
        return notification;
    }
}

希望这有帮助。

关于java - JAXB:将 XML 标记放在抽象类上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27236222/

相关文章:

php - 如何使用 PHP 获取原始 POST 数据并保存到文件中?

c++ - 在不转换对象的情况下调用子类方法

java - 未找到文本文件

java - 如何在字节缓冲区中表示目标列表

java.lang.IllegalStateException 您需要在此 Activity 中使用 Theme.AppCompat 主题(或后代)

c# - 使用 xsd 模式将 xml 数据中的黑名单字符

c# - 如果派生类继承基类的私有(private)成员,那么为什么不继承构造函数呢?

Java:初始化的内联私有(private)最终字段为空

java - 如何使用 jquery 文件上传插件激活 struts2 中的操作

java - 如何在终止前调用容器中每个 bean 的销毁方法