2016-05-12 25 views
1

我正在使用ECCP協議,以便將我的CRM與Elastix呼叫中心模塊集成。該協議使用定義的XML結構如下:JAX-B定製的XML輸出

<request id="1"> 
    <request_type> <!-- this will be mapped to the Java request class --> 
     <attributes> 
     </attributes> 
    </request_type> 
</request> 

<response id="1"> 
    <response_type> <!-- this will be mapped to the Java response class --> 
     <attributes> 
     </attributes> 
    </response_type> 
</response> 

我使用JAX-B到XML映射到Java類,但問題是,我必須把JAX- B在<request></request> XML中爲每個請求生成XML,並在每個響應中從<response></response>中提取內容,因爲ECCP協議定義每個請求和響應都需要嵌套到它們各自的元素。

下面是我使用這樣做的代碼:

document = createDocument(); 
Element requestWrapper = document.createElement("request"); 
requestWrapper.setAttribute("id", String.valueOf(wrapped.getId())); 
document.appendChild(requestWrapper); 

JAXBContext jc = JAXBContext.newInstance(wrapped.getClass()); 
Marshaller marshaller = jc.createMarshaller(); 
marshaller.marshal(wrapped, requestWrapper); 

例示:

一個ECCP的協議操作的是JAX-B-映射到這樣一類(getter和setter省略):

@XmlRootElement(name = "loginagent") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class EccpLoginAgentRequest implements IEccpRequest { 

    @XmlElement(name = "agent_number") 
    private String agentNumber; 

    @XmlElement(name = "password") 
    private String password; 
} 

和JAX-B輸出以下:

<loginagent> 
    <agent_number>username</agent_number> 
    <password>password</password> 
</loginagent> 

但什麼ECCP的協議要求是:

<request id="1"> <!-- id is an auto-increment number to identify the request --> 
    <loginagent> 
     <username>username</username> 
     <password>password</password> 
    </loginagent> 
</request> 

的問題是:是否有任何其他方式在任何其他更好的方式來實現? 謝謝。

回答

0

我找到了一種方法在這個崗位來解決這個問題:XML element with attribute and content using JAXB

所以我映射一個EccpRequestWrapper對象爲以下幾點:

@XmlRootElement(name = "request") 
public class EccpRequestWrapper { 
    @XmlAttribute 
    private Long id; 

    @XmlAnyElement 
    private IEccpRequest request; 
} 

,然後我的要求JAX-B輸出我的請求的方式ECCP協議要求。 @XmlAttribute@XmlAnyElement註解訣竅。

<request id="1"> 
    <login> 
     <username>user</username> 
     <password>****</password> 
    </login> 
</request> 

一個好的JAXB指南可以在這裏找到https://jaxb.java.net/guide/Mapping_interfaces.html

1

您可以查看@XmlSeeAlso註釋,它可以幫助您爲請求和響應包裝相同的內容。對於內部部分,您可以創建單獨的類並適當映射所有字段。我希望這可以幫助你一點點。

編輯: 對不起,很長的響應時間。您需要創建一個內部結構定義爲@XmlElement的包裝類。下面是實現這一目標的XML結構的方式:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement(name = "request") 
public class RequestWrapper { 

@XmlElement(name = "loginagent", required = true) 
protected EccpLoginAgentRequest loginagent; 

public EccpLoginAgentRequest getLoginagent() { 
    return loginagent; 
} 

public void setLoginagent(EccpLoginAgentRequest loginagent) { 
    this.loginagent = loginagent; 
} 
} 

而這裏的EccpLoginAgentRequest結構:

@XmlAccessorType(XmlAccessType.FIELD) 
public class EccpLoginAgentRequest { 

@XmlElement(name = "agent_number") 
private String agentNumber; 

@XmlElement(name = "password") 
private String password; 

// getters and setters omitted 
} 

所以結果是,你可以打印你想要這樣的XML:

JAXBContext jaxbContext = JAXBContext.newInstance(Wrapper.class); 
Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

EccpLoginAgentRequest request = new EccpLoginAgentRequest(); 
request.setAgentNumber("1"); 
request.setPassword("pass"); 

Wrapper wrapper = new Wrapper(); 
wrapper.setLoginagent(request); 

jaxbMarshaller.marshal(wrapper, System.out); 

它會給你以下輸出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<request> 
    <loginagent> 
     <agent_number>1</agent_number> 
     <password>pass</password> 
    </loginagent> 
</request> 
+0

好吧,我看了看在@XmlSeeAlso註釋文檔,但我會提高我的問題,以更好地解釋這個問題。 – Jaumzera

+0

如果您可以再次檢查問題,我會很高興。提前致謝。 – Jaumzera

+0

再次感謝@reallol,但它只會在我發送一個EccpLoginAgentRequest對象時起作用,而我真正需要的是能夠從任何擴展EccpRequest的類發送對象。 – Jaumzera