我们希望在webservice端点中启用有效负载的直接流式传输。我们必须处理大量的数据,并且希望在处理的同时流式传输数据。
我们在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标头已经写入我们的写入器,并在端点完成后关闭。不幸的是这是不可能的,流不能直接使用!流被包装在一个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()
方法使用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 ticket (SWS-704)。如果你想看到它的实现,可以考虑在JIRA页面上观看/投票。希望我们至少能得到一个有用的回复。
发布于 2011-07-21 19:25:32
您还必须禁用有效负载缓存:
<bean id="messageFactory"
class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="false"/>
</bean>
有了这个设置,我们终于能够使用Spring WS对SOAP执行直接流式处理了!
发布于 2011-04-05 09:20:15
您不能(永远不应该)在web服务中流式传输数据,因为随着时间的推移,在单个web服务请求中不断通过HTTP连接发送XML。您必须进行多个单独的web服务调用,或者将多个调用累积为一个。
如果你需要高性能,web服务不是很好。但是你可以手动优化简单的web服务,这并不难。但如果你需要更高的性能,换用另一款transport format会更划算。我仍然会通过HTTP保留内容--特别是如果您有一些身份验证要求的话。
发布于 2011-03-10 07:57:06
我只能想到一个黑客--栈(cxf,spring ws等)将缓冲整个消息,因为它们必须验证响应xml,以便能够在启用安全性的情况下计算密钥等。
因此,技巧是编写您自己的自定义servlet/spring控制器,它将处理这个特定的响应,并流出soap信封,然后是您的有效负载,然后是soap信封的结束标记。这是假设您没有任何WSS需求。
https://stackoverflow.com/questions/5165055
复制相似问题