Téléchargement de fichier JSF 2.0

je suis à la recherche autour de quelques blogs, pour essayer de trouver comment télécharger des fichiers en utilisant JSF 2.0 Mais toutes les solutions me déconcertent. Je voudrais savoir ce que je dois exactement pour être en mesure de télécharger avec succès un fichier(MP3, PDF, vidéo... que jamais taper) et le stocker dans une base de données en tant que @Lob. C'est ce que j'ai fait jusqu'à présent:

  • j'ai créé une entité qui a un attribut de type byte[] et il est également annoté avec une annotation @Lob.

  • j'ai créé une EJB qui introduira l'entité avec avec une méthode qui a un octet[] comme paramètre et l'insère dans la base de données en utilisant la classe EntityManager( méthode persist).

  • j'ai créé une page JSF avec une étiquette d'entrée de type "file" et un bouton "submit

  • j'ai préparé un bean géré pour échanger des informations sur le fichier avec la page JSF.

Maintenant je suis coincé, et j'ai beaucoup de doutes:

  • Que dois-je faire pour passer le fichier du JSF au bean managé et le transformer ensuite en byte[](pour pouvoir le traiter au EJB)?

  • comment un servlet peut-il m'aider?

  • ai-je besoin d'un servlet pour faire cela?

  • J'ai aussi découvert que dans certains blogs, il est question de servlets 3.0, mais je ne sais pas si mon environnement de travail l'utilise, comment le pourrais-je si j'utilise servlets 3.0 (j'utilise JEE6)?

Je n'ai jamais Téléchargé de fichier avant et aussi je ne suis pas très familier avec les servlets. Je suis confus, quelqu'un pourrait me donner quelques conseils, s'il vous plaît?

29
demandé sur BalusC 2011-03-24 14:20:46

8 réponses

tout d'abord, cette (ancienne) question et réponse suppose JSF 2.0/2.1. Depuis JSF 2.2 il y a un composant natif <h:inputFile> sans avoir besoin de bibliothèques de composants tiers. Voir aussi comment télécharger un fichier en utilisant JSF 2.2 ? Où est le fichier sauvegardé?


la manière la plus simple serait d'utiliser Tomahawk pour JSF 2.0 . Il offre un <t:inputFileUpload> composant.

voici un tutoriel étape par étape:

  • Créer un nouveau projet web dynamique pour la Servlet 3.0 et JSF 2.0. Le web.xml doit être conforme à la spécification Servlet 3.0 et contenir déjà le servlet JSF:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app 
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="YourProjectName" version="3.0">
    
        <display-name>Your Project Name</display-name>
    
        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>*.xhtml</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    le faces-config.xml doit être conforme JSF 2.0 spec:

    <?xml version="1.0" encoding="UTF-8"?>
    <faces-config
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
        version="2.0">
    
    </faces-config>
    

  • Télécharger Tomahawk 1.1.10 pour JSF 2.0 . Extraire le fichier zip, aller dans le dossier /lib et copier tous les fichiers *.jar dans votre /WEB-INF/lib .

    il s'agit de 18 fichiers, dont batik*.jar et xml*.jar ne sont pas nécessaires pour utiliser seul le composant t:inputFileUpload . Vous pourriez les laisser loin.


  • configurer le filtre des extensions Tomahawk dans web.xml . C'est celui qui est responsable du traitement des requêtes multipart/form-data qui est nécessaire pour pouvoir envoyer des fichiers via HTTP.

    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    

    notez que le <servlet-name> doit correspondre exactement au <servlet-name> du FacesServlet comme vous l'avez défini dans web.xml .


  • créer un simple Facelet, upload.xhtml :

    <!DOCTYPE html>
    <html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:t="http://myfaces.apache.org/tomahawk"
        xmlns:ui="http://java.sun.com/jsf/facelets">
        <h:head>
            <title>Tomahawk file upload demo</title>
        </h:head>
        <h:body>
            <h:form enctype="multipart/form-data">
                <t:inputFileUpload value="#{bean.uploadedFile}" />
                <h:commandButton value="submit" action="#{bean.submit}" />
                <h:messages />
            </h:form>
        </h:body> 
    </html>
    

    noter l'attribut enctype="multipart/form-data" sur <h:form> , C'est très important pour pouvoir envoyer des fichiers avec HTTP.


  • créer un haricot simple géré, com.example.Bean :

    package com.example;
    
    import java.io.IOException;
    
    import javax.faces.application.FacesMessage;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.RequestScoped;
    import javax.faces.context.FacesContext;
    
    import org.apache.commons.io.FilenameUtils;
    import org.apache.myfaces.custom.fileupload.UploadedFile;
    
    @ManagedBean
    @RequestScoped
    public class Bean {
    
        private UploadedFile uploadedFile;
    
        public void submit() throws IOException {
            String fileName = FilenameUtils.getName(uploadedFile.getName());
            String contentType = uploadedFile.getContentType();
            byte[] bytes = uploadedFile.getBytes();
    
            // Now you can save bytes in DB (and also content type?)
    
            FacesContext.getCurrentInstance().addMessage(null, 
                new FacesMessage(String.format("File '%s' of type '%s' successfully uploaded!", fileName, contentType)));
        }
    
        public UploadedFile getUploadedFile() {
            return uploadedFile;
        }
    
        public void setUploadedFile(UploadedFile uploadedFile) {
            this.uploadedFile = uploadedFile;
        }
    
    }
    

ça devrait être ça. Ouvrez-le par http://localhost:8080/projectname/upload.xhtml .

quant à vos questions concrètes:

que dois-je faire pour passer le fichier du JSF au bean géré et le transformer ensuite en octet[](pour pouvoir le traiter à la EJB)?

ceci est répondu ci-dessus.

comment un servlet peut-il m'aider?

il est capable de traiter et de contrôler les requêtes/réponses HTTP. Dans un environnement JSF, le FacesServlet déjà fait tout le travail.

ai-je besoin d'une servlet pour ce faire?

dans un environnement JSF, le FacesServlet est obligatoire. Mais c'est déjà fournies par l'API, vous n'avez pas besoin d'écrire vous-même. Cependant, pour pouvoir télécharger des fichiers à partir d'une base de données, un autre servlet est certainement utile. Vous pouvez trouver un exemple de base ici: Servlet pour servir du contenu statique .

aussi, j'ai trouvé que dans un blog il mentionne quelque chose sur servlets 3.0, mais je ne sais pas si mon environnement de travail est ussing il, comment si je suis ussing servlets 3.0(je suis ussing JEE6)?

si vous utilisez Servlet 3.0 container comme Glassfish 3, JBoss AS 6, Tomcat 7, etc et le web.xml est déclaré comme Servlet 3.0, alors vous utilisez certainement Servlet 3.0. Servlet 3.0 fait partie de Java EE 6.

66
répondu BalusC 2017-05-23 11:47:19

pour être complet, je veux juste fournir un entièrement fonctionnel exemple de la façon dont cela est fait avec JSF 2.2, soit avec des demandes Non-Ajax et Ajax . Gardez à l'esprit JSF 2.2 utilise différents espaces de noms et vous besoin de travailler avec un Servlet 3.0 conteneur (comme Tomcat 7.0.x, JBoss AS 6.x et 7.x et GlassFish 3.x sont).

fileUpload.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head />
<h:body>
    <h:form enctype="multipart/form-data">
        <h:inputFile value="#{uploadBean.file}" />
        <h:commandButton value="Post Upload" action="#{uploadBean.upload}" />
    </h:form>
    <h:form enctype="multipart/form-data">
        <h:inputFile value="#{uploadBean.file}" />
        <h:commandButton value="Ajax Upload">
            <f:ajax listener="#{uploadBean.upload}" execute="@form"
                render="countOutput" />
        </h:commandButton>
    <!-- Counts the uploaded items -->
    <h:outputText id="countOutput"
        value="Files uploaded #{uploadBean.filesUploaded}" />
    </h:form>
</h:body>
</html>

UploadBean.java:

@ManagedBean
@ViewScoped
public class UploadBean {

    private int filesUploaded = 0;

    //javax.servlet.http.Part (Servlet 3.0 API)
    private Part file;
    private String fileContent;

    /**
     * Just prints out file content
     */
    public void upload() {
        try {
            fileContent = new Scanner(file.getInputStream())
                    .useDelimiter("\A").next();
            System.out.println(fileContent + " uploaded");
            filesUploaded++;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public int getFilesUploaded() {
        return filesUploaded;
    }

    public Part getFile() {
        return file;
    }

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

Voir aussi:

6
répondu Xtreme Biker 2017-05-23 11:54:50

je recommande l'utilisation d'une bibliothèque companente comme Tomahawk's <t:inputFileUpload> ou PrimeFaces <p:fileUpload> .

BalusC a aussi un bel article de blog sur téléchargement de fichiers avec JSF 2.0 et Servlet 3.0.

3
répondu Mark 2012-12-19 14:56:38

dans JSF 2.2, vous pouvez facilement télécharger un fichier en utilisant tag sans utiliser commons-io ou filter. Cette balise supporte à la fois le processus normal et ajax.

Normal:

    <h:inputFile id="file"  value="#{fileUploadBean.uploadedFile}"/> 
    <h:commandButton id="button" action="#{fileUploadBean.sumbit()}" value="Upload"/>

Ajax:

    <h:inputFile id="file" value="#{fileUploadBean.uploadedFile}"/> 
    <h:commandButton id="button" value="submit">
      <f:ajax execute="@all" render="@all" onevent="statusUpdate"/>
    </h:commandButton>

Concevez votre haricot géré comme suit:

  @Named
  @RequestScoped
  public class FileUploadBean {

   private Part uploadedFile;

  }
2
répondu Masudul 2013-06-20 10:41:15

BalusC du blog: Téléchargement de fichiers avec JSF 2.0 et Servlet 3.0 est ce qui m'a sauvé, parce que j'avais des problèmes à l'exécution de RichFaces 4 fileUpload tag avec Spring WebFlow.

il vaut la peine de modifier le code de BalusC pour utiliser le MultipartResolver de Spring - vous n'avez pas besoin de son MultipartMap de un autre billet de blog .

Je l'ai obtenu en modifiant une méthode decode dans FileRenderer comme ceci:

    UploadedFile ret = null;

    Object req = context.getExternalContext().getRequest();
    if (req instanceof MultipartHttpServletRequest) {
      MultipartFile file = ((MultipartHttpServletRequest)req).getFile(clientId);

      File temp = null;
      try {
        temp = File.createTempFile("_UPLOAD_", null);
        file.transferTo(temp);

        String name = new File(file.getOriginalFilename()).getName();
        ret = new UploadedFile(temp, name);

      } catch (IOException e) {
        throw new RuntimeException("Could not create temp file.", e);
      }
    } else {
      throw new IllegalStateException("Request is not multipart. Use spring's multipart resolver.");
    }
    // If no file is specified, set empty String to trigger validators.
    ((UIInput) component).setSubmittedValue( ret == null ? EMPTY_STRING : ret);

A UploadedFile est un POJO sérialisable simple utilisé pour retourner les résultats à la fève de soutien.

1
répondu Maciek Łoziński 2013-01-08 14:42:04

la façon la plus simple est probablement d'utiliser l'étiquette inputFileUpload que vous pouvez trouver dans MyFaces:

http://myfaces.apache.org /

0
répondu Vladimir Ivanov 2011-03-24 11:28:36

IceFaces2.0 a un, http://wiki.icefaces.org/display/ICE/FileEntry N'ont pas encore essayé de le mettre en œuvre, mais le téléchargement a des applications échantillon et il fonctionne sous Tomcat 6 (servlet 2.5, donc pas JEE6)

0
répondu JimO 2011-03-24 14:11:07

vous devez ajouter commons-fileupload-1.2.1.jar dans notre chemin de construction de projet

1.Configurer web.fichier xml:

Web.xml

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    <mime-mapping>        
        <extension>png</extension>
        <mime-type>image/png</mime-type>
    </mime-mapping>

2. Create ManagedBean

   @ManagedBean
   @SessionScoped
public class FileUploadBean implements Serializable{
public FileUpload (){
}
  private StreamedContent file;
public void loadFile(FileUploadEvent event) throws IOException, InterruptedException {

        InputStream input = new ByteArrayInputStream(event.getFile().getContents());
        file= new DefaultStreamedContent(input, "image/jpg");
    }
}

3.fichier jsf (xhtml)

   <h:form enctype="multipart/form-data"> 
         <p:fileUpload fileUploadListener="#{fileUploadBean.file}" sizeLimit="100000" allowTypes="/(\.|\/)(gif|jpe?g|png|bmp)$/"/>
        </h:form>
0
répondu 2013-07-09 22:02:20