webentwicklung-frage-antwort-db.com.de

Hochladen von JSF 2.0-Dateien

Ich schaue mich in einigen Blogs um, um herauszufinden, wie man Dateien mit JSF 2.0 hochlädt. Aber all die Lösungen verwirren mich irgendwie. Ich möchte wissen, was genau ich brauche, um eine Datei (MP3, PDF, Video, was auch immer) erfolgreich hochladen und in einer Datenbank als @Lob speichern zu können. Das habe ich bisher gemacht:

  • Ich habe eine Entität erstellt, die ein Attribut vom Typ byte [] hat und außerdem mit einer @ Lob-Annotation versehen ist.

  • Ich habe eine EJB erstellt, die die Entität mit einer Methode einführt, die ein Byte [] als Parameter enthält, und diese mithilfe der EntityManager-Klasse in die Datenbank einfügt (persist-Methode).

  • Ich habe eine JSF-Seite mit einem Eingabe-Tag vom Typ "Datei" und einer Senden-Schaltfläche erstellt

  • Ich habe ein verwaltetes Bean vorbereitet, um Informationen über die Datei mit der JSF-Seite auszutauschen.

Jetzt stecke ich fest und habe viele Zweifel:

  • Was soll ich tun, um die Datei von der JSF an die verwaltete Bean zu übergeben und sie dann in ein Byte [] umzuwandeln (um sie an die EJB übergeben zu können)?

  • Wie kann mir ein Servlet helfen?

  • Benötige ich dazu ein Servlet?

  • Außerdem habe ich festgestellt, dass in einigen Blogs etwas über Servlets 3.0 erwähnt wird, aber ich weiß nicht, ob meine Arbeitsumgebung es verwendet. Wie kann ich es tun, wenn ich Servlets 3.0 verwende (ich verwende JEE6)?

Ich habe noch nie Dateien hochgeladen und bin auch nicht sehr vertraut mit Servlets. Ich bin verwirrt, könnte mir jemand ein paar Starttipps geben, bitte?

33
sfrj

Zuallererst setzt diese (alte) Frage und Antwort JSF 2.0/2.1 voraus. Seit JSF 2.2 gibt es eine native <h:inputFile> - Komponente ohne Bibliotheken von Drittanbietern. Siehe auch Wie lade ich eine Datei mit JSF 2.2 <h: inputFile> hoch? Wo befindet sich die gespeicherte Datei?


Der einfachste Weg wäre Tomahawk für JSF 2. . Es bietet eine <t:inputFileUpload> Komponente.

Hier ist eine Schritt-für-Schritt-Anleitung:

  • Erstellen Sie ein leeres dynamisches Webprojekt für Servlet 3.0 und JSF 2.0. Das web.xml Muss der Servlet 3.0-Spezifikation entsprechen und bereits das JSF-Servlet enthalten:

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

    Der faces-config.xml Muss der JSF 2.0-Spezifikation entsprechen:

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

  • Download Tomahawk 1.1.10 für JSF 2. . Extrahieren Sie die Zip-Datei, wechseln Sie in den Ordner /lib Und kopieren Sie alle *.jar - Dateien in Ihren /WEB-INF/lib.

    Es sind 18 Dateien, von denen batik*.jar Und xml*.jar Nicht erforderlich sind, um allein die Komponente t:inputFileUpload Zu verwenden. Sie könnten sie weglassen.


  • Konfigurieren Sie den Tomahawk-Erweiterungsfilter in web.xml. Es ist derjenige, der für die Bearbeitung von multipart/form-data - Anfragen verantwortlich ist, die erforderlich sind, um Dateien über HTTP senden zu können.

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

    Beachten Sie, dass der <servlet-name> Genau mit dem <servlet-name> Des FacesServlet übereinstimmen muss, wie Sie es in web.xml Definiert haben.


  • Erstellen Sie ein einfaches 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>
    

    Beachten Sie das Attribut enctype="multipart/form-data" Unter <h:form>. Dies ist sehr wichtig, um Dateien mit HTTP senden zu können.


  • Erstellen Sie eine einfache verwaltete Bean, 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;
        }
    
    }
    

Das sollte es sein. Öffnen Sie es mit http: // localhost: 8080/projectname/upload.xhtml .

Zu Ihren konkreten Fragen:

Was soll ich tun, um die Datei von der JSF an die verwaltete Bean zu übergeben und sie dann in ein Byte [] umzuwandeln (um sie an die EJB übergeben zu können)?

Dies wird oben beantwortet.

Wie kann mir ein Servlet helfen?

Es kann HTTP-Anfragen/-Antworten verarbeiten und steuern. In einer JSF-Umgebung erledigt FacesServlet bereits die gesamte Arbeit.

Brauche ich dazu ein Servlet?

In einer JSF-Umgebung ist FacesServlet obligatorisch. Aber es wird bereits von der API bereitgestellt, Sie müssen selbst keine schreiben. Um jedoch Dateien aus einer Datenbank herunterladen zu können, ist ein anderes Servlet auf jeden Fall nützlich. Ein einfaches Beispiel finden Sie hier: Servlet zum Bereitstellen statischer Inhalte .

Auch ich fand, dass in einigen Blogs etwas über Servlets 3.0 erwähnt wird, aber ich weiß nicht, ob meine Arbeitsumgebung es verwendet, wie kann ich, wenn ich Servlets 3.0 verwende (ich verwende JEE6)?

Wenn Sie einen Servlet 3.0-Container wie Glassfish 3, JBoss AS 6, Tomcat 7 usw. verwenden und web.xml Als Servlet 3.0 deklariert ist, verwenden Sie auf jeden Fall Servlet 3.0. Servlet 3.0 ist Teil von Java EE 6.

70
BalusC

Der Vollständigkeit halber möchte ich nur ein voll funktionsfähiges eigenständiges Beispiel dafür geben, wie dies mit JSF 2.2 gemacht wird, entweder mit Nicht-Ajax- oder Ajax-Anfragen . Beachten Sie, dass JSF 2.2 verschiedene Namespaces verwendet und Sie müssen mit einem Servlet 3.0-Container arbeiten (wie Tomcat 7.0.x, JBoss AS 6.x und 7.x und GlassFish 3.x).

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

Siehe auch:

8
Xtreme Biker

Ich würde empfehlen, eine Companent-Bibliothek wie Tomahawk's <t:inputFileUpload> oder PrimeFaces <p:fileUpload> zu verwenden.

BalusC hat auch einen netten Blogeintrag über Hochladen von Dateien mit JSF 2.0 und Servlet 3.0.

3
Mark

Der Blog-Beitrag von BalusC: Hochladen von Dateien mit JSF 2.0 und Servlet 3. hat mich gerettet, weil ich Probleme hatte, RichFaces 4 fileUpload-Tag mit Spring WebFlow auszuführen.

Es lohnt sich, den Code von BalusC so zu ändern, dass er Frühlings MultipartResolver verwendet - Sie brauchen seinen MultipartMap nicht aus einem anderen Blog-Beitrag .

Ich habe es erreicht, indem ich eine decode -Methode in FileRenderer wie folgt geändert habe:

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

Ein UploadedFile ist ein einfaches serialisierbares POJO, mit dem die Ergebnisse an das Backing Bean zurückgegeben werden.

2

In JSF 2.2 können Sie Dateien einfach mit Tags hochladen, ohne Commons-io oder Filter zu verwenden. Dieses Tag unterstützt sowohl den normalen als auch den Ajax-Prozess.

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>

Entwerfen Sie Ihre Managed Bean wie folgt:

  @Named
  @RequestScoped
  public class FileUploadBean {

   private Part uploadedFile;

  }
2
Masudul

Sie müssen commons-fileupload-1.2.1.jar In unseren Projekterstellungspfad einfügen

1.Konfigurieren Sie die Datei web.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. Erstellen Sie 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.jsf datei (xhtml)

   <h:form enctype="multipart/form-data"> 
         <p:fileUpload fileUploadListener="#{fileUploadBean.file}" sizeLimit="100000" allowTypes="/(\.|\/)(gif|jpe?g|png|bmp)$/"/>
        </h:form>
0
user2354035

Am einfachsten ist es wahrscheinlich, das inputFileUpload-Tag zu verwenden, das Sie in MyFaces finden:

http://myfaces.Apache.org/

0
Vladimir Ivanov

IceFaces2.0 hat eine, http://wiki.icefaces.org/display/ICE/FileEntry Habe noch nicht versucht, sie zu implementieren, aber der Download enthält Beispiel-Apps und funktioniert unter Tomcat 6 (Servlet) 2.5, also nicht JEE6)

0
JimO