我将大文件上传到我的服务器应用程序(Tomcat7,JSF2.2,PrimeFaces)时遇到问题。我想上传最大5 GB的文件。这需要很多时间,并且短连接丢失的可能性非常高。
目前我尝试了primefaces fileupload。这可以工作,但是如果我丢失了网络连接,那么上传就会直接停止,而无需客户端或服务器端的任何反馈。
有没有办法让它可靠?
此外,恢复文件上传的可能性非常好。
答案 0 :(得分:0)
我会尽力回答我的问题......
将上传可靠并可恢复到JSF / Primefaces Web应用程序的最佳方法是集成Javascript库 resumable.js (或基于它的类似库)。
它使用许多现代浏览器支持的HTML5文件API。
集成/执行:
在客户端,您必须集成resumable.js
库和一些Javascript代码来处理上传。为此,resumable.js
库提供了一些事件,如uploadStart,fileSuccess等等。
结合PrimeFaces <p:remoteCommand>
,您可以从Javascript与服务器端Web应用程序进行通信。
代码示例:添加resumable.js JavaScript库
<h:outputScript library="js" name="resumable.js" />
代码示例:初始化可恢复对象
var r;
var maxFileSize = #{uploadDataBean.getUploadSizeLimit()};
var allowedFileExtensions = #{uploadDataBean.getFileTypes()};
function pageLoaded() {
PF('wVarStartBtn').disable();
r = new Resumable({
target: '../upload',
chunkSize: 1*1024*1024,
forceChunkSize: true,
prioritizeFirstAndLastChunk: false,
simultaneousUploads: 3,
testChunks: true,
chunkRetryInterval: 1000,
maxFiles: 1,
maxFilesErrorCallback: callbackMaxFiles,
maxFileSize: maxFileSize,
maxFileSizeErrorCallback: callbackMaxFileSize,
fileType: allowedFileExtensions,
fileTypeErrorCallback: callbackFileType,
method: "octet"
});
r.assignDrop($('.resumable-drop')[0]);
r.assignBrowse($('.resumable-select')[0]);
// ### resumable event functions ###
r.on('fileAdded', function(file) {
console.log("File added: Name = " + file.fileName + ", No. of Chunks = " + file.chunks.length);
...
}
...
}
代码示例:从Javascript到托管Bean的通信
<h:form id="hiddenInputsForm" prependId="false" style="display:none;">
<p:remoteCommand name="rcStartUpload" update=":msg :msgs" actionListener="#{uploadDataBean.uploadStarted()}" />
<p:remoteCommand name="rcUploadComplete" update=":msg :msgs" actionListener="#{uploadDataBean.uploadComplete()}" />
<p:remoteCommand name="rcAddFile" update="hiddenInputsForm" />
<h:inputText id="fileupload-hidden-input-filename" value="#{uploadDataBean.fileName}" />
<h:inputText id="fileupload-hidden-input-fileidentifer" value="#{uploadDataBean.fileIdentifier}" />
<h:inputText id="fileupload-hidden-input-filesize" value="#{uploadDataBean.fileSize}" />
<h:inputText id="fileupload-hidden-input-chunksize" value="#{uploadDataBean.chunkSize}" />
</h:form>
<script type="text/javascript">
...
function pageLoaded() {
...
// ### resumable event functions ###
r.on('fileAdded', function(file) {
console.log("File added: Name = " + file.fileName + ", No. of Chunks = " + file.chunks.length);
document.getElementById('fileupload-hidden-input-filename').value = file.fileName;
document.getElementById('fileupload-hidden-input-fileidentifer').value = file.uniqueIdentifier;
document.getElementById('fileupload-hidden-input-filesize').value = file.size;
document.getElementById('fileupload-hidden-input-chunksize').value = file.chunks.length;
rcAddFile();
});
r.on('uploadStart', function () {
console.log("Upload started");
rcStartUpload();
})
r.on('fileSuccess', function(file) {
console.log("File upload success");
rcUploadComplete();
});
...
}
</script>
服务器端需要WebFilter来接收来自resumable.js的GET和POST请求。您必须从doFilter
接口实现javax.servlet.Filter
方法。
此过滤器类使用另一个类(例如UploadFileManager)和静态方法来检查是否已收到块并保存不存在的块。
如果上载完成,则客户端可以通过RemoteCommand调用其托管bean。 Bean本身可以通过静态方法通过相同的UploadFileManager类访问上载的文件。
注意:带有静态方法的UploadFileManager类必须是线程安全的!