2011-03-02 112 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