2011-03-02 111 views
16

我們希望能夠在web服務端點直接傳輸我們的有效載荷。我們必須處理大量的數據,並希望在處理數據時對數據進行流式處理。如何使用Spring-WS直接使用SOAP進行SOAP?

我們使用spring-ws-core,版本2.0.0,並使用PayloadRootQNameEndpointMapping作爲終點映射器。作爲消息工廠,我們使用AxiomSoapMessageFactory。我們實施了StreamingPayload和相應的writeTo(XMLStreamWriter writer)方法,我們用它來編寫我們的有效載荷(根據spring-ws JIRA票證,SWS-352)。

這工作正常沒有任何錯誤,但我們想直接流!這顯然是不可能的。我們通過流式傳輸一些數據來評估行爲,我們做了一個簡單的測試。

writer.writeStartElement("exampleResponse") 

10000.times 
{ 
    writer.writeStartElement("example") 
    writer.writeEndElement()  
} 

writer.writeEndElement() 

我們假定這將直接傳輸到消費者/客戶端,所以肥皂頭已經寫入到我們的作家和端點完成後關閉。不幸的是,這是不可能的,該流不能直接使用!流包裹在一個ByteArrayInputStream,在spring-ws源文件中找到。

StreamingOMDataSource的實現顯示了這一點(可以在springs FishEye中查看)。 StreamingOMDataSource調用您的StreamingPayload實現併爲您提供一個編寫器。

public XMLStreamReader getReader() throws XMLStreamException { 
    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    serialize(bos, null); 

    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 
    return StAXUtils.createXMLStreamReader(bis); 
} 

方法#serialize()創建XMLStreamWriterByteArrayOutputStream並調用有效載荷,能寫入,如上所述。

public void serialize(OutputStream output, OMOutputFormat format) 
     throws XMLStreamException 
{ 
    XMLStreamWriter streamWriter; 
    if ([...]) { 
     // Create stream writer with defined charset 
    } 
    else { 
     streamWriter = StAXUtils.createXMLStreamWriter(output); 
    } 
    serialize(streamWriter); 
} 

public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException { 
    payload.writeTo(xmlWriter); 
    xmlWriter.flush(); 
} 

因此,這是不適合我使用。是否有可能實現直接流式傳輸?任何想法?先謝謝你!


更新:我終於春季WS創建JIRA ticket (SWS-704)。如果你想看看它的實現,可以考慮在JIRA頁面上觀看/投票。希望我們至少得到一個有用的答覆。

+0

我沒有看到SWS-352允許流式傳輸?你知道web服務通過HTTP正確嗎? – ThomasRS 2011-04-05 01:06:05

回答

4

你必須也禁用有效載荷緩存:

<bean id="messageFactory" 
     class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory"> 
    <property name="payloadCaching" value="false"/> 
</bean> 

通過這個設置,我們終於能夠與Spring WS的SOAP進行直接流!

0

我只能想到這個問題 - 堆棧(cxf,spring ws等)會緩衝整個消息,因爲它們必須驗證響應xml,以便能夠在啓用安全性時計算加密密鑰等。

所以黑客會寫你自己的定製servlet/spring控制器來處理這個特定的響應,然後流出肥皂包,然後是你的有效負載,然後是肥皂包的結束標籤。假設您沒有任何WSS要求。

2

您無法(絕不應該)在Web服務中流式傳輸數據,例如在單個Web服務請求中持續通過HTTP連接發送XML。你將不得不做很多單一的網絡服務呼叫,或積累多個呼叫到一個。

如果您需要高性能,網絡服務不是很好。但是,您可以手動優化簡單的Web服務,但並不困難。但如果您需要更高的性能,切換到另一個transport format會更「賺錢」。我仍然保持HTTP的東西 - 特別是如果你有一些認證要求。

+0

如果糟糕的是提供流式Web服務,爲什麼JAX-WS RI會以流式方式提供對發送和接收大型附件的支持?我們將考慮分塊數據傳輸,但Spring-WS實現仍然沒有用處!你能解釋一下基於webservices/HTTP的流式實現有什麼問題嗎? – codevour 2011-04-05 08:00:02

+0

流式API更高效,替代方法是構建DOM樹。它被稱爲流媒體API,但這僅適用於創建XML。實際上,如果接收方(webservice端點)沒有讀取完整的請求,驗證它,然後整體處理其有效內容,那麼您無法保證,實際上它會很奇怪。 – ThomasRS 2011-04-05 14:00:40

+0

保持你的眼睛在球上;你想流式傳輸你的數據,你不需要做webservice流式傳輸來實現這一點?你需要什麼類型的性能,你有沒有你發送的XML的例子? – ThomasRS 2011-04-05 14:07:53