2014-12-01 32 views
1

我使用來自第三方的界面,他們有一個特殊的(在我看來至少)的請求/響應,並通知XML格式。該XML需要看起來像這樣:JAXB:在抽象類將XML標籤

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

Request標籤也可能是NotificationResponse之一。所有Messages將只有這三個中的一個。 RequestResponse都有RequestIDResponse也有ReturnValueNotification s有Session

爲了防止重複我想創造一個抽象類這三種類型的,它幾乎作品!我可以編組和解組從這個樣子的:

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

注意失蹤Request標籤! NotificationResponse相同。所有信息都在那裏,但這些包裝標籤正在殺死我!

問題: 我可以把XML標籤上的抽象類?或者,我是否需要使其成爲非抽象的,並創建另一個頂級抽象類作爲「真正的」抽象基類?

我有JAXB沒有太多的經驗,所以我希望有一個簡單的方法來做到這一點。我試圖使報文中的request領域的XMLElement代替,但只有改變Request_Name標籤Request並增加了一個類型規範。

我的代碼基本上如下,以取出來簡潔制定者和構建函數。

基部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; 
    } 
} 

一個例子Request實現:

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

上述被編組是這樣的:爲NotificationResponse類似

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

回答

1

你所需要的就是一個RequestContainer類具有標籤名請求。這個類將包含實際的請求實現。這是必需的,因爲JAXB會將每個類作爲單獨的標記呈現。標籤層次結構不是基於類層次結構構建的。

容器類將是這個樣子:

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

同樣,對於NotificationResponse。該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; 
    } 
} 

希望這有助於。

+0

這實際上非常接近我結束了。我會發布我的解決方案,但會標記你的正確。 – Dennis 2014-12-03 11:25:35