将大型文件上传到服务器应用程序(Tomcat7、JSF2.2、PrimeFaces)有问题。我想上传高达5GB的文件。这需要很长时间,短连接丢失的概率很高。
目前,我尝试了原始脸丝状体。这是可行的,但如果我失去了网络连接,然后上传直接停止,没有任何反馈的客户端或服务器端。
有什么办法让它可靠吗?
此外,恢复文件上传的可能性也是很好的。
发布于 2015-12-02 13:39:20
我会尽力回答我的问题..。
使上载可靠并可恢复到JSF/Primefaces web应用程序的最佳方法是集成Javascript库resumable.js (或基于它的类似library )。
它使用了许多现代浏览器支持的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类必须是线程安全!
构件图
https://stackoverflow.com/questions/27550589
复制相似问题