wake-up-neo.com

So speichern Sie eine hochgeladene Datei in JSF

Ich lade eine Datei in JSF hoch. Ich verwende dazu Tomahawks <t:inputFileUpload>, aber die gleiche Frage trifft auf z. PrimeFaces <p:fileUpload> und JSF 2.2 <h:inputFile>.

Ich habe den untenstehenden Unterstützungsbohnencode:

private UploadedFile uploadedFile; // +getter+setter

public String save() throws IOException {
    String name = uploadedFile.getName();
    System.out.println("File name: " + name);

    String type = uploadedFile.getContentType();
    System.out.println("File type: " + type);

    long size = uploadedFile.getSize();
    System.out.println("File size: " + size);  

    InputStream stream = uploadedFile.getInputStream();
    byte[] buffer = new byte[(int) size];  
    stream.read(buffer, 0, (int) size);  
    stream.close();  
}

Ich kann den Dateinamen, den Typ und die Größe abrufen, kann diese Datei jedoch nicht unter einem bestimmten Pfad speichern. Ich kann die richtige Methode zum Speichern der hochgeladenen Datei nicht herausfinden. Wie kann ich das erreichen?

16
V.Rohan

Die getInputStream()-Methode der hochgeladenen Datei repräsentiert den Dateiinhalt. 

InputStream input = uploadedFile.getInputStream();

Sie müssen es in eine Datei kopieren. Sie sollten zunächst einen Ordner im lokalen Festplatten-Dateisystem vorbereiten, in dem die hochgeladenen Dateien gespeichert werden sollen. Beispiel: /path/to/uploads (unter Windows befindet sich dies auf derselben Festplatte wie der Server). Beachten Sie, dass Sie unbedingt die Dateien nicht im erweiterten WAR-Ordner ablegen sollten. Verwenden Sie dazu einen relativen Pfad oder getRealPath() aus den hier genannten Gründen Hochgeladene Bilder sind nur nach dem Aktualisieren der Seite verfügbar .

Dann müssen Sie den Dateinamen automatisch generieren. Wenn ein anderer Benutzer später eine Datei zufällig mit demselben Namen hochlädt, wird diese Datei überschrieben. Sie können Files#createTempFile() facility verwenden, um einen automatisch generierten Dateinamen zu erhalten. 

Path folder = Paths.get("/path/to/uploads");
String filename = FilenameUtils.getBaseName(uploadedFile.getName()); 
String extension = FilenameUtils.getExtension(uploadedFile.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);

Der Pfad zu den Uploads kann bei Bedarf anhand einer der folgenden Möglichkeiten parametrisiert werden: Empfohlene Methode zum Speichern der hochgeladenen Dateien in einer Servlet-Anwendung . Die Variable FilenameUtils ist Teil von Apache Commons IO, das Sie bereits in Ihrem Klassenpfad enthalten sollten, da es von der Tomahawk-Komponente zum Hochladen von Dateien abhängt.

Zum Schluss streamen Sie einfach die hochgeladene Datei in diese Datei (unter der Voraussetzung von Java 7):

try (InputStream input = uploadedFile.getInputStream()) {
    Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}

System.out.println("Uploaded file successfully saved in " + file);

Um es zurück herunterzuladen, wäre es am einfachsten, /path/to/uploads als neuen Webapp-Kontext oder als virtuellen Host zu registrieren, damit alle diese Dateien über eine URL verfügbar sind. Siehe auch Bilder von außerhalb des Ordners webapps/webcontext/deploy laden mit <h: graphicImage> oder <img> tag .

52
BalusC

PrimeFaces verwendet zwei Datei-Upload-Decoder zum Hochladen von Inhalten von p: fileupload 

  1. NativeFileUploadDecoder
  2. CommonsFileUploadDecoder

NativeFileUploadDecoder ist der Standard-Upload-Decoder und erfordert den Servlet-Container 3.0. Wenn Ihr Servlet-Container also weniger als 3 ist, funktioniert er nicht bei Ihnen. Auch einige Anwendungsserver beschränken die Verwendung von mehrteiligem Inhalt 

Wenn Sie also aus irgendeinem Grund ein Problem mit dem nativen Upload-Decoder haben, müssen Sie den anderen Decoder verwenden, der "CommonsFileUploadDecoder" ist.

CommonsFileUploadDecoder hängt von der allgemeinen Apache von Apache ab Daher müssen Sie die commons-fileupload- und commons-io-Jars in Ihren Klassenpfad einlegen Die Version hängt von Ihrer Version der Primefaces ab für mich.

um CommonsFileUploadDecoder verwenden zu können, müssen Sie einen Filter verwenden 

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

warte nur der Filter funktioniert nicht, da innerhalb des Filters nach dem Uploader gesucht wird, wenn er nicht bereitgestellt wird, und mindestens JSF 2.2 erkannt wird, sodass die Anforderung an den Standarddecodierer "Native" umgangen wird und dies dann der Fall ist Arbeitet auch nicht für Sie 

um den Filter zu zwingen, den allgemeinen Decoder zu verwenden, müssen Sie den folgenden Kontextparameter in Ihre web.xml einfügen

<context-param>
<param-name>primefaces.UPLOADER</param-name>
   <param-value>commons</param-value>
</context-param>
1
HMoussa