我已经写了一个小的应用程序,会让人上载和下载文件给我。我已经增加了一个网服务这火车乘客应提供上载/下载功能的方式,但我不太确定如何以及我的执行是要应付大型文件。

在目前的定义的上载和下载方法看起来像这样(书面使用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)这当然会尽量把所有的信息存入内存和碰撞我的服务。

所以我的问题是它可能回到某种流,而不是?我想这不会是可怕的操作系统无关。虽然我知道背后的理论网服务、实际的一面是什么,我仍然需要一位信息。

欢呼声的任何输入, 李

有帮助吗?

解决方案

Stephen Denne 有一个满足您要求的Metro实施。在简短的探讨之后,我的答案将在下面提供。为什么会这样。

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

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

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

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

其他提示

是的,这是有可能用地铁。看看 大附件 例如,这看起来像它一样你想要什么。

贾克斯-WS RI提供支助的发送和接收大附件一流时尚。

  • 使用MTOM和DataHandler在编程模型。
  • 投DataHandler到StreamingDataHandler和使用它的方法。
  • 确保你叫StreamingDataHandler.close()并且也关闭StreamingDataHandler.readOnce()流。
  • 启用HTTP块上的客户。

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

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

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

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

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

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

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

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

很多人都不知道所有这些东西都是基于流的节目,只是在它上面分层了多少东西。有些人会说太多东西 - 我就是其中之一。

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

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

您需要设置transferMode =" StreamedResponse"在httpTransport配置中并使用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,客户端可以做出决定,包括推送的速率。

实际上并不难以“处理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,因此您最终可能会在浏览器上出现错误,但实际上就是它的全部内容。

祝你好运!

罗德尼

scroll top