我正在使用来自第三方的接口(interface),他们有一种特殊的(至少在我看来)用于请求/响应和通知的 XML 格式。 XML 需要如下所示:
<Message>
<Version>3.1</Version>
<Request>
<Request_Name>
<RequestID> Request ID </RequestID>
...
</Request_Name>
</Request>
</Message>
Request
标记也可以是 Notification
或 Response
之一。所有消息
都只有这三者之一。 Request
和 Response
都有 RequestID
。 Response
也有 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>
最佳答案
这里您需要的是一个具有标签名称Request的RequestContainer
类。此类将包含实际的请求实现。这是必需的,因为 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/