如何使用Spring-WS直接传输SOAP?
我们希望在Web服务端点中启用有效负载的直接流式传输。 我们必须处理大量数据,并希望在处理时流式传输数据。
我们在版本2.0.0中使用spring-ws-core,并使用PayloadRootQNameEndpointMapping
作为端点映射器。 作为消息工厂,我们使用的是AxiomSoapMessageFactory
。 我们实现StreamingPayload
和相应的writeTo(XMLStreamWriter writer)
方法,我们用它来编写有效负载(根据spring-ws JIRA票证, SWS-352 )。
这没有任何错误,但我们想直接流! 这显然是不可能的。 我们做了一个简单的测试,我们流式传输一些数据来评估行为。
writer.writeStartElement("exampleResponse") 10000.times { writer.writeStartElement("example") writer.writeEndElement() } writer.writeEndElement()
我们假设这将直接流式传输到使用者/客户端,因此soap头已经写入我们的编写器并在端点完成后关闭。 不幸的是,这是不可能的,流不能直接使用! 流被包装在Spring-ws源中的ByteArrayInputStream
中。
StreamingOMDataSource
的实现显示了这一点(可以在SpringEye中查看)。 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()
使用ByteArrayOutputStream
创建XMLStreamWriter
,并调用有效负载以启用写入,如上所述。
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(); }
所以这对我来说无法使用。 是否有可能实现直接流媒体? 有什么想法吗? 先感谢您!
更新 :我最终为Spring WS创建了一个JIRA票证(SWS-704) 。 如果你想看到它实现,请考虑在JIRA页面上观看/投票。 希望我们至少得到一个有用的答复。
您还必须禁用有效负载缓存:
通过此设置,我们终于可以使用Spring WS执行SOAP的直接流式传输!
您不能(绝不应该)在Web服务中流式传输数据,就像在一个Web服务请求中通过HTTP连接不断地发送XML一样。 您必须进行许多单个Web服务调用,或将多个调用累积到一个中。
如果您需要高性能,Web服务并不是很好。 但是你可以手工优化简单的网络服务,这并不难。 但是,如果您需要更高的性能,切换到另一种传输格式将更多“钱”。 我仍然通过HTTP保存 – 特别是如果你有一些身份validation要求。
我只能想到这一点 – 堆栈(cxf,spring ws等)将缓冲整个消息,因为它们必须validation响应xml,以便能够在启用安全性时计算加密密钥等。
所以黑客就是编写你自己的自定义servlet / spring控制器,它将处理这个特定的响应并流出肥皂信封,然后是你的有效负载,然后是肥皂信封的结束标记。 这假设您没有任何WSS要求。