Web服务可以返回流吗?

我一直在写一个小应用程序,让人们上传和下载文件给我。 我已经为这个applciation添加了一个Web服务来提供上传/下载function,但是我不太确定我的实现将如何处理大文件。

目前,上传和下载方法的定义如下所示(使用Apache CXF编写):

boolean uploadFile(@WebParam(name = "username") String username, @WebParam(name = "password") String password, @WebParam(name = "filename") String filename, @WebParam(name = "fileContents") byte[] fileContents) throws UploadException, LoginException; byte[] downloadFile(@WebParam(name = "username") String username, @WebParam(name = "password") String password, @WebParam(name = "filename") String filename) throws DownloadException, LoginException; 

因此文件作为字节数组上传和下载。 但是,如果我有一个愚蠢的大小(例如1GB)的文件肯定会尝试将所有信息放入内存并使我的服务崩溃。

所以我的问题是 – 是否有可能返回某种流? 我想这不会是非常独立的操作系统。 虽然我知道Web服务背后的理论,但实际的一面是我还需要了解一些信息。

为任何输入干杯,李

Stephen Denne的Metro实现可满足您的要求。 在简短的探讨之后,我的答案将在下面提供。

使用HTTP作为消息协议构建的大多数Web服务实现都符合REST,因为它们只允许简单的发送 – 接收模式,仅此而已。 这极大地提高了互操作性,因为所有各种平台都可以理解这种简单的体系结构(例如,与Web Web服务通信的Java Web服务)。

如果你想保持这个,你可以提供分块。

 boolean uploadFile(String username, String password, String fileName, int currentChunk, int totalChunks, byte[] chunk); 

如果你没有按照正确的顺序获得块,那么这需要一些步法(或者你可以只需要按正确的顺序排列块),但它可能很容易实现。

是的,可以使用Metro。 请参阅大型附件示例,它看起来像您想要的那样。

JAX-WS RI支持以流方式发送和接收大型附件。

  • 在编程模型中使用MTOM和DataHandler。
  • 将DataHandler转换为StreamingDataHandler并使用其方法。
  • 确保调用StreamingDataHandler.close()并关闭StreamingDataHandler.readOnce()流。
  • 在客户端启用HTTP分块。

当您使用标准化Web服务时,发送方和接收方确实依赖于从一方发送到另一方的XML数据的完整性。 这意味着仅在发送最后一个标记时才完成Web服务请求和应答。 考虑到这一点,Web服务不能被视为流。

这是合乎逻辑的,因为标准化Web服务确实依赖于http协议。 那个是“无国籍”,会说它的工作方式就像“打开连接……发送请求……接收数据……关闭请求”。 无论如何,连接将在最后关闭。 所以像流媒体这样的东西不打算在这里使用。 或者他在http之上(如Web服务)。

很抱歉,但据我所知,网络服务不可能流式传输。 更糟糕的是:取决于Web服务的实现/配置,byte [] – 数据可能会被转换为Base64而不是CDATA标签,并且请求可能会变得更加臃肿。

PS:是的,正如其他人写的那样,“chuinking”是可能的。 但这不是流媒体;-) – 无论如何,它可能会帮助你。

我讨厌将其分解为那些认为无法实现流式网络服务的人,但实际上,所有的http请求都是基于流的。 每个对网站进行GET的浏览器都是基于流的。 每次调用Web服务都是基于流的。 是的,全部。 我们在实现服务或页面的层面上没有注意到这一点,因为较低级别的架构正在为您处理这个问题 – 但它正在完成。

你有没有注意到在浏览器中有时需要一段时间来获取页面 – 浏览器只是不停地显示沙漏? 那是因为浏览器正在等待流。

流是mime /类型必须在实际数据之前发送的原因 – 它只是浏览器的字节流,如果你没有告诉它它是什么,它将无法识别照片。 这也是为什么你必须在发送之前传递二进制文件的大小 – 浏览器将无法分辨图像停止的位置并且页面再次被拾取。

它只是客户端的字节流。 如果你想自己certificate这一点,只需在处理请求的任何时候保持输出流并关闭()它。 你会炸毁一切。 浏览器将立即停止显示沙漏,并将显示“无法找到”或“在服务器上重置连接”或其他此类消息。

很多人都不知道所有这些东西都是基于流的,显示了它上面已经分层了多少东西。 有人会说太多东西 – 我就是其中之一。

祝你好运,快乐发展 – 放松肩膀!

对于WCF,我认为可以将消息上的成员定义为流并适当地设置绑定 – 我已经看到这项工作与wcf谈论Java Web服务。

您需要在httpTransport配置中设置transferMode =“StreamedResponse”并使用mtomMessageEncoding(需要在配置中使用自定义绑定部分)。

我认为一个限制是,如果您想要流式传输(哪种有意义),您只能拥有一个邮件正文成员。

Apache CXF支持发送和接收流。

一种方法是添加uploadFileChunk (byte [] chunkData,int size,int offset,int totalSize)方法(或类似的东西),上传部分文件,服务器将其写入磁盘。

请记住,Web服务请求基本上归结为单个HTTP POST。

如果查看.NET中.ASMX文件的输出,它会准确显示POST请求和响应的样子。

正如@Guvante所提到的,Chunking将是最接近你想要的东西。

我想你可以实现自己的Web客户端代码来处理TCP / IP并将内容传输到你的应用程序中,但至少可以说这很复杂。

我认为使用一个简单的servlet来完成这个任务会更简单,或者你有什么理由不能使用servlet吗?

例如,您可以使用Commons开源库。

用于Java的RMIIO库提供了跨RMI处理RemoteInputStream – 我们只需要RMI,尽管您应该能够调整代码以适应其他类型的RMI。 这可能对您有所帮助 – 特别是如果您可以在用户端使用小型应用程序。 开发这个库的目的是为了能够限制推送到服务器的数据大小,以避免你描述的情况类型 – 通过填充ram或磁盘实际上是DOS攻击。

使用RMIIO库,服务器端可以决定它愿意提取多少数据,在HTTP PUT和POST的情况下,客户端可以做出决定,包括推送的速率。

是的,网络服务可以做流式传输。 我使用Apache Axis2和MTOM创建了一个Web服务,以支持从XML呈现PDF文档。 由于生成的文件可能非常大,因此流式传输非常重要,因为我们不希望将其全部保存在内存中。 查看Oracle有关流式SOAP附件的文档。

或者,您可以自己完成,tomcat将创建Chunked标头。 这是流式传输的弹簧控制器function的示例。

  @RequestMapping(value = "/stream") public void hellostreamer(HttpServletRequest request, HttpServletResponse response) throws CopyStreamException, IOException { response.setContentType("text/xml"); OutputStreamWriter writer = new OutputStreamWriter (response.getOutputStream()); writer.write("this is streaming"); writer.close(); } 

实际上并不难“处理TCP / IP并将内容流入应用程序”。 尝试这个…

 class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { response.getOutputStream().println("Hello World!"); } } 

这就是它的全部。 在上面的代码中,您已经响应了从浏览器发送的HTTP GET请求,并在文本“Hello World!”中返回到该浏览器。

请记住“Hello World!” 是无效的HTML,因此您最终可能会在浏览器上出现错误,但这就是它的全部内容。

在你的发展中祝你好运!

罗德尼