2016-04-05 6 views
0

Ich fand dieses sehr schöne Beispiel für Dateiupload mit JSF 2.2. Ist es möglich, Fortschrittsbalken mit Prozent des Datei-Uploads oder der gesamten hochgeladenen Bytes hinzuzufügen?Zeige Fortschrittsprozentsatz von h: Inputfile Upload

<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> 

Bean:

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!")); 
      } 
     } 
    } 
} 

Ist dies möglich, ohne zusätzliche JavaScript-Code? Nur mit JSF?

+0

überprüfte ich den Link. Ist der Web-Socket in 2.3.0-m05 implementiert? Kannst du mir bitte ein Beispiel zeigen? –

+0

Ich benutze Apache-Tomcat-8.0.33 –

+0

Weld-Servlet, 2.3.3.Final –

Antwort

1

fand ich, dass die Malsup Form plugin for jQuery ziemlich einfach ist und eine gute Dokumentation und Demo-Code (also ziemlich einfach, einen Fortschrittsbalken verwenden, um Ajaxify) , wenn Sie bereit sind, die jQuery (Javascript) Weg zu gehen. (Natürlich können auch andere Plugins gibt es auch, wie die BlueImp file uploader plugin die eine Menge mehr Möglichkeiten hat, kann aber nicht ganz so einfach zu bedienen sein.)

Für einen „JSF-only“ -Lösung, BalusC recommends using a JSF component library like Primefaces - das ist wahrscheinlich eine bessere Option - es wird empfohlen, seine Kommentare und Links zu lesen, die die Gründe für die Bevorzugung der einen Technologie gegenüber der anderen erklären.

=== am Beispiel ===

Hier ist ein sehr einfaches Beispiel, die Malsup Formular-Plugin und jQuery verwenden, die die Fortschrittsbalken zeigen. (Es behandelt auch andere Felder auf dem Formular, wenn man will, aber lesen Sie auf die Profis & Nachteile der verschiedenen enctype -Einstellungen in der <form> Element.) Beachten Sie, dass eine <div> mit einem Fortschrittsbalken und eine Textbeschriftung angibt, Fortschritt Prozentsatz angezeigt wird, und eine andere <div> zeigen einige Text nach Abschluss des Prozesses - eines dieser Elemente kann weggelassen oder auf andere Weise angepasst werden. Diese <div> s werden über CSS formatiert und von verschiedenen Event-Handlern im Javascript aktualisiert. In der Java-Backing-Bean wird keine Arbeit ausgeführt.

Hinweis:

Ich hoffe, das liegt auf der Hand, aber die * JS-Dateien im Verzeichnis <my-eclipse-project>/WebContent/resources/js/ gespeichert werden für die <h:outputScript> Tags korrekt zu arbeiten.

1. XHTML-Sicht, einschließlich CSS und 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. Backing Bean

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 
} 
+0

Können Sie mir ein Beispiel mit JavaScript zeigen? –

+0

@PeterPenzov: ein grundlegendes Beispiel hinzugefügt – fr13d