【问题标题】:Show progress percentage of h:inputFile upload显示 h:inputFile 上传进度百分比
【发布时间】:2016-04-05 14:06:15
【问题描述】:

我发现了这个使用 JSF 2.2 上传文件的非常好的示例。是否可以添加带有文件上传百分比或上传总字节数的进度条?

<script type="text/javascript">
            function progressBar(data) {
                if (data.status === "begin") {
                    document.getElementById("uploadMsgId").innerHTML="";
                    document.getElementById("progressBarId").setAttribute("src", "./resources/progress_bar.gif");
                }
                if (data.status === "complete") {
                    document.getElementById("progressBarId").removeAttribute("src");
                }
            }
        </script>

<h:messages id="uploadMsgId" globalOnly="true" showDetail="false" showSummary="true" style="color:red"/>
<h:form id="uploadFormId" enctype="multipart/form-data">
    <h:inputFile id="fileToUpload" required="true" requiredMessage="No file selected ..." value="#{uploadBean.file}"/>
    <h:message showDetail="false" showSummary="true" for="fileToUpload" style="color:red"/>
    <h:commandButton value="Upload" action="#{uploadBean.upload()}">
        <f:ajax execute="fileToUpload" onevent="progressBar" render=":uploadMsgId @form"/>
    </h:commandButton>
</h:form>
<div>
    <img id="progressBarId" width="250px;" height="23"/>
</div>

豆:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.Part;

@Named
@RequestScoped
public class UploadBean {

    private static final Logger logger = Logger.getLogger(UploadBean.class.getName());
    private Part file;

    public Part getFile() {
        return file;
    }

    public void setFile(Part file) {
        this.file = file;
    }

    public void upload() {

        if (file != null) {

            logger.info("File Details:");
            logger.log(Level.INFO, "File name:{0}", file.getName());
            logger.log(Level.INFO, "Content type:{0}", file.getContentType());
            logger.log(Level.INFO, "Submitted file name:{0}", file.getSubmittedFileName());
            logger.log(Level.INFO, "File size:{0}", file.getSize());

            try (InputStream inputStream = file.getInputStream(); FileOutputStream outputStream = new FileOutputStream("C:" + File.separator + "jsf_files_test_for_delete" + File.separator +file.getSubmittedFileName())) {

                int bytesRead = 0;
                final byte[] chunck = new byte[1024];
                while ((bytesRead = inputStream.read(chunck)) != -1) {
                    outputStream.write(chunck, 0, bytesRead);
                }

                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Upload successfully ended!"));
            } catch (IOException e) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Upload failed!"));
            }
        }
    }
}

如果没有额外的 JavaScript 代码,这可能吗?仅使用 JSF?

【问题讨论】:

  • 我检查了链接。网络套接字是否在 2.3.0-m05 中实现?你能给我举个例子吗?
  • 我用的是apache-tomcat-8.0.33
  • weld-servlet,2.3.3.Final

标签: jsf jsf-2.2


【解决方案1】:

我发现Malsup Form plugin for jQuery 相当简单并且有很好的文档和演示代码(因此相当容易使用 Ajaxify 进度条)如果你准备走 jQuery (Javascript) 路线。 (当然,其他插件也存在,比如BlueImp file uploader plugin,它有很多更多可能性,但可能不是那么容易使用。)

对于“仅限 JSF”的解决方案,BalusC recommends using a JSF component library like Primefaces - 这可能是一个更好的选择 - 建议阅读他的 cmets 和他提供的链接,这些链接解释了偏爱一种技术的原因。

=== 添加示例 ===

这是一个非常基本的示例,使用 Malsup Form 插件和 jQuery,演示了进度条。 (如果需要,它还处理表单上的其他字段,但请阅读&lt;form&gt; 元素中不同enctype 设置的优缺点。)请注意,&lt;div&gt; 带有进度条和文本显示指示进度百分比的标签,另一个&lt;div&gt; 显示过程完成时的一些文本 - 这些元素中的任何一个都可以省略或以其他方式自定义。这些&lt;div&gt;s 通过 CSS 设置样式,并由 Javascript 中的各种事件处理程序更新。 Java backing bean 中没有做任何工作。

注意:

我希望这很明显,但 *.js 文件保存在目录 &lt;my-eclipse-project&gt;/WebContent/resources/js/ 中,以便 &lt;h:outputScript&gt; 标记正常工作。

1. XHTML 视图,包括 CSS 和 Javascript

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
>
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Demo File upload with progress</title>

    <style>
        .progress {
            position: relative;
            width: 400px;
            border: 1px solid #ddd;
            padding: 1px;
            border-radius: 3px;
        }

        .bar {
            background-color: #B4F5B4;
            width: 0%;
            height: 20px;
            border-radius: 3px;
        }

        .percent {
            position: absolute;
            display: inline-block;
            top: 3px;
            left: 48%;
        }
    </style>

    <h:outputScript target="head" library="js" name="jquery.js" />
    <h:outputScript target="head" library="js" name="jquery.form.js" /><!-- http://jquery.malsup.com/form/ -->
    <h:outputScript target="body">  
        //<![CDATA[
        jQuery(document).ready(function() {
            var bar = jQuery('.bar');
            var percent = jQuery('.percent');
            var status = jQuery('#status');

            jQuery('#formid').ajaxForm({
                beforeSend: function() {
                    status.empty();
                    var percentVal = '0%';
                    bar.width(percentVal)
                    percent.html(percentVal);
                },
                uploadProgress: function(event, position, total, percentComplete) {
                    var percentVal = percentComplete + '%';
                    bar.width(percentVal)
                    percent.html(percentVal);
                },
                success: function() {
                    var percentVal = '100%';
                    bar.width(percentVal)
                    percent.html(percentVal);
                },
                complete: function(xhr) {
                    status.html(xhr.statusText);
                }
            }); 
        });
        //]]>
    </h:outputScript>
</h:head>
<h:body>
    <h:form id="formid" enctype="multipart/form-data" method="post">
        <h1>Demo File upload with progress</h1>
        <h:messages globalOnly="true" tooltip="true" />

        <h:inputFile id="fileupload" name="fileupload" value="#{uploadBean.file}" />
        <div class="progress">
            <div class="bar"></div>
            <div class="percent">0%</div>
        </div>
        <div id="status"></div>
        <br />
        <h:inputText value="#{uploadBean.field}"></h:inputText>
        <br />
        <h:commandButton id="submit" action="#{uploadBean.submit}" value="Submit" />
    </h:form>
</h:body>
</html>

2。支持豆

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.servlet.http.Part;

@ManagedBean
@ViewScoped
public class UploadBean implements Serializable {
    private static final long   serialVersionUID    = 1L;

    private String              field;
    private Part                file;

    /** Constructor */
    public UploadBean() {}

    /** Action handler */
    public String submit() {
        // the file is already uploaded at this point
        // TODO whatever you need to do with the file and other form values
        return ""; // ... or another view
    }

    // TODO getters and setters for fields
}

【讨论】:

  • @PeterPenzov:添加了一个基本示例
猜你喜欢
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多