Java JAXB:在抽象类上放置XML标记

Java JAXB:在抽象类上放置XML标记,java,xml,inheritance,jaxb,Java,Xml,Inheritance,Jaxb,我使用的是来自第三方的接口,它们有一种特殊的(至少在我看来)XML格式用于请求/响应和通知。XML需要如下所示: <Message> <Version>3.1</Version> <Request> <Request_Name> <RequestID> Request ID </RequestID> ... </Request_Name> </

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

<Message>
  <Version>3.1</Version>
  <Request>
    <Request_Name>
      <RequestID> Request ID </RequestID>
      ...
    </Request_Name>
  </Request>
</Message>
<Message>
  <Version>3.1</Version>
  <Request_Name>
    <RequestID> Request ID </RequestID>
    ...
  </Request_Name>
</Message>
<?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>
@XmlRootElement(name = "Request")
public class RequestContainer {
   private Request request;
}
请注意缺少的
Request
标记!同样适用于
通知
响应
。所有的信息都在那里,但是这些包装标签快把我累死了

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

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

我的代码基本上如下所示,为了简洁起见,去掉了setter和ctor

基本
消息
类:

@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;
    }
}
抽象
请求
类。类似于
通知
响应

@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;
    }
}
上面的数据被编组为如下内容:

<Message>
  <Version>3.1</Version>
  <Request>
    <Request_Name>
      <RequestID> Request ID </RequestID>
      ...
    </Request_Name>
  </Request>
</Message>
<Message>
  <Version>3.1</Version>
  <Request_Name>
    <RequestID> Request ID </RequestID>
    ...
  </Request_Name>
</Message>
<?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>
@XmlRootElement(name = "Request")
public class RequestContainer {
   private Request request;
}

8.3
94668
548248
真的
在我需要的地方:

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

8.3
94668
548248
真的

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

容器类将如下所示:

<Message>
  <Version>3.1</Version>
  <Request>
    <Request_Name>
      <RequestID> Request ID </RequestID>
      ...
    </Request_Name>
  </Request>
</Message>
<Message>
  <Version>3.1</Version>
  <Request_Name>
    <RequestID> Request ID </RequestID>
    ...
  </Request_Name>
</Message>
<?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>
@XmlRootElement(name = "Request")
public class RequestContainer {
   private Request request;
}
类似地,对于
通知
响应
消息
类将包含以下每个类的容器类实例:

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

希望这能有所帮助。

这实际上与我的结局非常接近。我也会发布我的解决方案,但会将你的标记为正确。