【问题标题】:Is there a way to upload large files reliable using JSF2.2有没有办法使用JSF2.2可靠地上传大文件
【发布时间】:2015-12-03 18:53:32
【问题描述】:

我无法将大文件上传到我的服务器应用程序(Tomcat7、JSF2.2、PrimeFaces)。我想上传最大 5 GB 的文件。这需要很多时间,而且短连接丢失的可能性非常高。

目前我尝试了 primefaces 文件上传。这可行,但如果我失去了网络连接,那么上传会直接停止,而客户端或服务器端没有任何反馈。

有没有办法让它可靠?

还可以恢复文件上传。

【问题讨论】:

    标签: jsf file-upload primefaces


    【解决方案1】:

    我会尽量回答我的问题...

    使上传可靠且可恢复到 JSF/Primefaces Web 应用程序的最佳方法是集成 Javascript 库 resumable.js(或基于它的类似库)。

    它使用许多现代浏览器都支持的 HTML5 File 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 请求。您必须从javax.servlet.Filter 接口实现doFilter 方法。 此过滤器类使用另一个具有静态方法的类(例如 UploadFileManager)来检查是否已收到块并保存不存在的块。 如果上传完成,那么客户端可以通过 RemoteCommand 调用他们的托管 bean。 Bean本身可以通过同一个UploadFileManager类通过静态方法访问上传的文件。

    注意:带有静态方法的 UploadFileManager 类必须是线程安全的!

    Component diagram

    【讨论】:

    • 请将此代码显示到:" 结合 PrimeFaces RemoteCommand,您可以从 Javascript 与服务器站点 Web 应用程序进行通信。"
    • @Kukeltje:我在上面的评论中添加了一个代码 sn-p。
    猜你喜欢
    • 2016-12-26
    • 2012-05-22
    • 2019-03-26
    • 1970-01-01
    • 2021-08-21
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多