我需要将一些通用java客户端的二进制文件传输到使用servlet技术的服务器 问题出现了,因为我需要检查发送给我的一些数据,以便授权上传。此外,我还需要有关该文件的其他信息,以便对其进行特征化(名称,作者,...)。
我的意思是:
(A)使用通过默认输入流接收请求的GenericServlet。它将读取预先格式化的数据结构,然后如果数据正常,它将读取并保存文件
(B)使用HttpServlet并进行常规的http文件上传(这将需要客户端环境中的http支持)并使用一些post属性来获取其他数据。
现在问题: 选项A:
有没有一种方法可以在文件之前获取初始数据,以便首先对它们进行处理,然后只有在数据正常的情况下允许文件传输才能限制数据存储时的内存使用情况不好?
如果文件很长并且以N个部分到达服务器,并且servlet在客户端完成发送所有N个部分之前检查其他信息发现它们不好,有没有办法通过在转移期间回答客户端以打破“糟糕”和沉重的请求来打破转移?
我可以在同一个请求中将多个Java对象(例如自定义FileInfo类)与二进制文件一起传输吗?
选项B:
总是使用http是一个很好的实践吗?
设置multipart数据类型后,文件内容是作为post变量的内容发送的吗?
感谢
答案 0 :(得分:1)
两个选项都很好,但B比A更灵活。我刚刚在工作中实现选项B来替换/隐藏传统协议。在我看来,使用HTTP是一种很好的做法:它不会很快消失,几乎任何编程语言都有很好的支持。此外,管理员还有许多工具可用于授权请求,直接流量和监控负载。
我选择了以下设置:
客户端使用Apache的HttpClient和HttpMime执行由两部分组成的帖子(请参阅多部分帖子示例here)。第一部分是包含所有必需元数据的JSON(UTF-8)字符串。此JSON字符串通过Map< String,Object>进行编码/解码,使用Jackson的示例为here。第二部分是文件上传(FileBody-part)。
服务器是Tomcat Servlet,它使用Commons FileUpload接收这两个部分。第一个JSON部分首先被预期并经过验证。如果不是,则servlet立即发送“NOK”响应(例如“Bad request”)。然后接收并处理该文件。
我为元数据选择了JSON,因为这是一种易于理解的格式(像XML一样可读)并且在web-world中得到了很好的支持。另一种方法是使用http-headers作为参数并将文件作为正文发送(可能更容易实现)。
我选择了Apache的HttpMime和Common的FileUpload,因为它们可以很好地协同工作。不难理解这些应该如何协同工作(研究这些例子),我还没有遇到一个真正难以解决的问题。此外,Apache的HttpClient 4.3最终默认支持函数(例如(de)压缩请求),我之前不得不跳到箍。
但对我来说是第一:文件数据的处理是流式传输。我通过在Apache HttpClient动态压缩的多部分发布请求中上传2GB文件来证实这一点。客户端和服务器都没有声称有任何额外的内存来处理这个大文件(但它确实需要一些时间来传输所有的字节)。
由于HTTP的性质,我担心一旦启动后客户端就无法停止发送文件数据。但这应该不是问题,因为这将是一种特殊的情况,而不是常态。