Java 如何在SpringWS中使用SOAP的直接流?

Java 如何在SpringWS中使用SOAP的直接流?,java,spring,soap,streaming,spring-ws,Java,Spring,Soap,Streaming,Spring Ws,我们希望在webservice端点中启用负载的直接流。我们必须处理大量数据,并希望在处理过程中对数据进行流式处理 我们在版本2.0.0中使用SpringWS-core,并使用PayloadRootQNameEndpointMapping作为端点映射器。作为消息工厂,我们使用的是公理soapmessagefactory。我们实现了StreamingPayload和相应的writeTo(XMLStreamWriter)方法,我们使用它来编写我们的有效负载(根据spring ws-JIRA票据,) 这

我们希望在webservice端点中启用负载的直接流。我们必须处理大量数据,并希望在处理过程中对数据进行流式处理

我们在版本2.0.0中使用SpringWS-core,并使用
PayloadRootQNameEndpointMapping
作为端点映射器。作为消息工厂,我们使用的是
公理soapmessagefactory
。我们实现了
StreamingPayload
和相应的
writeTo(XMLStreamWriter)
方法,我们使用它来编写我们的有效负载(根据spring ws-JIRA票据,)

这工作正常,没有任何错误,但我们想直接流!这显然是不可能的。我们做了一个简单的测试,通过流式传输一些数据来评估行为

writer.writeStartElement("exampleResponse")

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

writer.writeEndElement()
我们假设这将直接流式传输到消费者/客户机,因此soap头已经写入我们的编写器,并在端点完成后关闭。不幸的是,这是不可能的,流不能直接使用!该流被封装在spring ws源代码中的
ByteArrayInputStream

StreamingOMDataSource
的实现显示了这一点(可以在中查看)。
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();
}
所以这对我来说是不可用的。是否可以实现直接流式传输?有什么想法吗?提前谢谢你



更新:我终于为SpringWS创建了一个。如果你想看到它的执行,就可以考虑在JILA页面上观看/投票。希望我们至少能得到一个有用的答复。

我只能想到一个解决方案——堆栈(cxf、spring ws等)将缓冲整个消息,因为它们必须验证响应xml,以便在启用安全性等情况下能够计算加密密钥

因此,黑客将编写您自己的定制servlet/spring控制器,该控制器将处理这个特定的响应,并输出soap信封,然后是您的负载,然后是soap信封的结束标记。这是假设您没有任何WSS要求。

您不能(永远不应该)在web服务中流式传输数据,就像在一个web服务请求中通过HTTP连接不断发送XML一样。您将不得不进行多个单独的web服务调用,或者将多个调用累积到一个调用中


如果您需要高性能,web服务就不是很好。但您可以手动优化简单的web服务,这并不难。但是,如果你需要更高的性能,那么换一个会更“赚钱”。我仍然会通过HTTP保留内容-尤其是如果您有一些身份验证要求。

您还必须禁用有效负载缓存:

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


通过这个设置,我们最终能够使用SpringWS为SOAP执行直接流式处理

我看不出SWS-352允许流媒体?您知道Web服务是通过HTTP的,对吧?如果提供流式Web服务有那么糟糕,为什么JAX-WS RI提供了对以流式方式发送和接收大型附件的支持?我们将考虑分块数据传输,但SpringWS实现仍然没有用处!你能解释一下基于webservices/HTTP的流媒体实现有什么问题吗?流媒体API更有效,另一种方法是构建DOM树。它被称为流式API,但这仅适用于创建XML。你不能保证,事实上,如果接收者(webservice端点)没有读取完整的请求,验证它,然后作为一个整体处理它的负载,这将是非常奇怪的;您想要流式传输您的数据,您不需要通过webservice流式传输来实现吗?您需要什么样的性能?您有发送xml的示例吗?